diff --git a/test/qr.cob b/test/qr.cob index 5641e21..361a580 100644 --- a/test/qr.cob +++ b/test/qr.cob @@ -4,15 +4,18 @@ DATA DIVISION. WORKING-STORAGE SECTION. 01 QR-PTR USAGE POINTER. - 01 QR-VERSION PIC S9(9) COMP-5. - 01 QR-WIDTH PIC S9(9) COMP-5. - 01 QR-DATA-PTR USAGE POINTER. 01 WS-TEXT PIC X(20) VALUE "unsandbox-qr-ok" & X"00". 01 WS-ZERO PIC S9(9) COMP-5 VALUE 0. 01 WS-ONE PIC S9(9) COMP-5 VALUE 1. 01 WS-TWO PIC S9(9) COMP-5 VALUE 2. + LINKAGE SECTION. + 01 QR-STRUCT. + 05 QR-VERSION PIC S9(9) COMP-5. + 05 QR-WIDTH PIC S9(9) COMP-5. + 05 QR-DATA USAGE POINTER. + PROCEDURE DIVISION. MAIN-LOGIC. CALL "QRcode_encodeString" @@ -24,8 +27,7 @@ RETURNING QR-PTR. IF QR-PTR NOT = NULL - SET ADDRESS OF QR-VERSION TO QR-PTR - SET ADDRESS OF QR-WIDTH TO QR-PTR + SET ADDRESS OF QR-STRUCT TO QR-PTR DISPLAY "QR:unsandbox-qr-ok:ROWS:" QR-WIDTH CALL "QRcode_free" USING BY VALUE QR-PTR ELSE diff --git a/test/qr.d b/test/qr.d index 69d302c..87b94cf 100644 --- a/test/qr.d +++ b/test/qr.d @@ -1,8 +1,33 @@ +import core.sys.posix.dlfcn; import std.stdio; -import qr; +import std.string; + +struct QRcode { + int _version; + int width; + void* data; +} void main() { - auto qrCode = QrCode("unsandbox-qr-ok"); - auto size = qrCode.size; - writefln("QR:unsandbox-qr-ok:ROWS:%d", size); + auto lib = dlopen("libqrencode.so", RTLD_LAZY); + if (lib is null) { + stderr.writeln("dlopen: ", dlerror().fromStringz); + return; + } + + alias EncFunc = extern(C) QRcode* function(const char*, int, int, int, int); + alias FreeFunc = extern(C) void function(QRcode*); + + auto encode = cast(EncFunc) dlsym(lib, "QRcode_encodeString"); + auto qfree = cast(FreeFunc) dlsym(lib, "QRcode_free"); + + auto qr = encode("unsandbox-qr-ok", 0, 1, 2, 1); + if (qr is null) { + stderr.writeln("encode failed"); + return; + } + + writefln("QR:unsandbox-qr-ok:ROWS:%d", qr.width); + qfree(qr); + dlclose(lib); } diff --git a/test/qr.f90 b/test/qr.f90 index ed74f84..7ec775e 100644 --- a/test/qr.f90 +++ b/test/qr.f90 @@ -2,27 +2,31 @@ program qrcode_test use, intrinsic :: iso_c_binding implicit none + ! QRcode struct layout: version(int), width(int), data(ptr) type, bind(C) :: QRcode integer(c_int) :: version integer(c_int) :: width type(c_ptr) :: data end type QRcode + ! C function interfaces interface type(c_ptr) function dlopen(filename, flag) bind(C, name='dlopen') import :: c_ptr, c_char, c_int character(kind=c_char), dimension(*), intent(in) :: filename integer(c_int), value :: flag - end function + end function dlopen + type(c_funptr) function dlsym(handle, symbol) bind(C, name='dlsym') import :: c_ptr, c_funptr, c_char type(c_ptr), value :: handle character(kind=c_char), dimension(*), intent(in) :: symbol - end function - integer(c_int) function dlclose(handle) bind(C, name='dlclose') + end function dlsym + + integer(c_int) function f_dlclose(handle) bind(C, name='dlclose') import :: c_ptr, c_int type(c_ptr), value :: handle - end function + end function f_dlclose end interface abstract interface @@ -30,11 +34,11 @@ program qrcode_test import :: c_ptr, c_char, c_int character(kind=c_char), dimension(*), intent(in) :: s integer(c_int), value :: ver, lvl, hint, cs - end function + end function encode_iface subroutine free_iface(qr) bind(C) import :: c_ptr type(c_ptr), value :: qr - end subroutine + end subroutine free_iface end interface type(c_ptr) :: lib, qr_ptr @@ -42,8 +46,9 @@ program qrcode_test procedure(encode_iface), pointer :: qr_encode procedure(free_iface), pointer :: qr_free type(QRcode), pointer :: qr + integer(c_int) :: rc - lib = dlopen("libqrencode.so" // c_null_char, 2) ! RTLD_NOW=2 + lib = dlopen("libqrencode.so" // c_null_char, 2) enc_fptr = dlsym(lib, "QRcode_encodeString" // c_null_char) free_fptr = dlsym(lib, "QRcode_free" // c_null_char) call c_f_procpointer(enc_fptr, qr_encode) @@ -54,5 +59,5 @@ program qrcode_test write(*, '(A,I0)') 'QR:unsandbox-qr-ok:ROWS:', qr%width call qr_free(qr_ptr) - call dlclose(lib) + rc = f_dlclose(lib) end program qrcode_test diff --git a/test/qr.fs b/test/qr.fs index 11812df..3d9b5d3 100644 --- a/test/qr.fs +++ b/test/qr.fs @@ -1,6 +1,21 @@ -open QRCoder +open System +open System.Runtime.InteropServices -let gen = QRCodeGenerator() -let data = gen.CreateQrCode("unsandbox-qr-ok", QRCodeGenerator.ECCLevel.M) -let rows = data.ModuleMatrix.Count -printfn "QR:unsandbox-qr-ok:ROWS:%d" rows +[] +extern nativeint QRcode_encodeString(string text, int version, int level, int hint, int caseSensitive) + +[] +extern void QRcode_free(nativeint qr) + +[] +type QRcode = + val version: int + val width: int + +let qr = QRcode_encodeString("unsandbox-qr-ok", 0, 1, 2, 1) +if qr <> IntPtr.Zero then + let s = Marshal.PtrToStructure(qr) + printfn "QR:unsandbox-qr-ok:ROWS:%d" s.width + QRcode_free(qr) +else + printfn "QR encode failed" diff --git a/test/qr.hs b/test/qr.hs index 0e3da19..ff11252 100644 --- a/test/qr.hs +++ b/test/qr.hs @@ -1,11 +1,41 @@ -import Codec.QRCode -import Codec.QRCode.JuicyPixels +import System.Posix.DynamicLinker +import Foreign +import Foreign.C.Types +import Foreign.C.String + +data QRcode = QRcode CInt CInt (Ptr Word8) + +instance Storable QRcode where + sizeOf _ = 16 + alignment _ = 8 + peek ptr = QRcode + <$> peekByteOff ptr 0 + <*> peekByteOff ptr 4 + <*> peekByteOff ptr 8 + poke _ _ = return () + +type EncodeFunc = CString -> CInt -> CInt -> CInt -> CInt -> IO (Ptr QRcode) +type FreeFunc = Ptr QRcode -> IO () + +foreign import ccall "dynamic" + mkEncode :: FunPtr EncodeFunc -> EncodeFunc + +foreign import ccall "dynamic" + mkFree :: FunPtr FreeFunc -> FreeFunc main :: IO () main = do - let mqr = encodeText defaultQRCodeOptions Iso8859_1OrUtf8WithoutECI "unsandbox-qr-ok" - case mqr of - Nothing -> putStrLn "QR encode failed" - Just img -> do - let matrix = toMatrix True False img :: [[Bool]] - putStrLn $ "QR:unsandbox-qr-ok:ROWS:" ++ show (length matrix) + dl <- dlopen "libqrencode.so" [RTLD_LAZY] + encFP <- dlsym dl "QRcode_encodeString" + freeFP <- dlsym dl "QRcode_free" + let encode = mkEncode encFP + let qfree = mkFree freeFP + cs <- newCString "unsandbox-qr-ok" + qr <- encode cs 0 1 2 1 + if qr == nullPtr + then putStrLn "QR encode failed" + else do + QRcode _ w _ <- peek qr + putStrLn $ "QR:unsandbox-qr-ok:ROWS:" ++ show w + qfree qr + free cs diff --git a/test/qr.ml b/test/qr.ml index 4d7f238..565f95d 100644 --- a/test/qr.ml +++ b/test/qr.ml @@ -1,4 +1,27 @@ +#use "topfind";; +#require "ctypes";; +#require "ctypes.foreign";; + +open Ctypes;; +open Foreign;; + +type qrcode +let qrcode : qrcode structure typ = structure "QRcode";; +let _qr_version = field qrcode "version" int;; +let qr_width = field qrcode "width" int;; +let _qr_data = field qrcode "data" (ptr char);; +let () = seal qrcode;; + +let encode_string = + foreign "QRcode_encodeString" + (string @-> int @-> int @-> int @-> int @-> returning (ptr qrcode));; + +let qr_free = + foreign "QRcode_free" + (ptr qrcode @-> returning void);; + let () = - let qr = Qrc.encode "unsandbox-qr-ok" in - let rows = Array.length (Qrc.to_matrix qr) in - Printf.printf "QR:unsandbox-qr-ok:ROWS:%d\n" rows + let qr = encode_string "unsandbox-qr-ok" 0 1 2 1 in + let w = getf !@qr qr_width in + Printf.printf "QR:unsandbox-qr-ok:ROWS:%d\n" w; + qr_free qr;; diff --git a/test/qr.nim b/test/qr.nim index 6fbe25a..a83c437 100644 --- a/test/qr.nim +++ b/test/qr.nim @@ -1,4 +1,27 @@ -import qr +import dynlib -let qrCode = newQR("unsandbox-qr-ok") -echo "QR:unsandbox-qr-ok:ROWS:" & $qrCode.size +type + QRcode {.pure.} = object + version: cint + width: cint + data: pointer + +type + QRencodeString = proc(s: cstring, ver: cint, level: cint, hint: cint, cs: cint): ptr QRcode {.cdecl.} + QRfree = proc(qr: ptr QRcode) {.cdecl.} + +let lib = loadLib("libqrencode.so") +if lib == nil: + quit("Failed to load libqrencode.so", 1) + +let encode = cast[QRencodeString](lib.symAddr("QRcode_encodeString")) +let free_qr = cast[QRfree](lib.symAddr("QRcode_free")) + +let qr = encode("unsandbox-qr-ok", 0, 1, 2, 1) +if qr != nil: + echo "QR:unsandbox-qr-ok:ROWS:", qr.width + free_qr(qr) +else: + echo "QR encode failed" + +unloadLib(lib)