Artifact Content

Artifact e32eaa7c6e40d7c0da01c6fc678e8f070e7c8d97d9282654bfef25504402a1f7:

Wiki page [jimff] by grable 2018-11-24 12:45:52.
D 2018-11-24T12:45:52.149
L jimff
P 961323ddc2b9cb5d6dca2f82eb3a430094e51c187d94b4b43bfb7359cba75545
U grable
W 3392

A foreign function interface extension for <a href="">jimtcl</a> using the excellent <a href="">ffcall</a> library and the platform dynamic library loader.

  > lappend auto_path .
  > package require jimff
  > jimff ff
  > ff::info -help
    ff::load      ?-noerror? library... | -self
    ff::import    ?-function | -variable | -pointer? ?-self | library? {name ?alias?} typetag
    ff::callback  ?name? command typetag | -update name command
    ff::pointer   -alloc size | -realloc pointer newsize | -free pointer | -forget pointer | -take pointer ?size? | -size pointer ?newsize? | -null ?pointer? | -validate pointer
    ff::unwrap    ?-packed? pointer typetag ?varNames...?
    ff::wrap      ?-packed? pointer typetag values...
    ff::gets      pointer ?offset? ?varName?
    ff::read      pointer ?offset? length
    ff::write     pointer ?offset? string
    ff::copy      destination ?offset? source ?offset? length
    ff::info      -help | -libraries | -symbols ?library? | -functions ?library? | -variables ?library? | -callbacks ?-typetags | -commands?
  > ff::info -typetags
        v       {void}
        b       {unsigned char}
        c       {signed char}
        C       {unsigned char}
        s       {short}
        S       {unsigned short}
        i       {signed int}
        I       {unsigned int}
        l       {signed long}
        L       {unsigned long}
        w       {signed long long}
        W       {unsigned long long}
        q       {signed long long}
        Q       {unsigned long long}
        f       {float}
        d       {double}
        p       {void*}
        x       {callback_t}
        z       {const char*}
        Z       {char*}
        a       {int32_t | float | void*}
        A       {int64_t | double | void*}
  > set lib [ff::load test_lib.dll]
  > ff::import -function $lib {__malloc	malloc}	Pi
  > ff::import -function $lib {__strcpy	strcpy}	ppz	
  > ff::import -function $lib {__strcat	strcat}	ppz
  > ff::import -function $lib {__free	free}	vP
  > ff::import -function test_callback vzx
  > set test_1 [ff::callback test_1 iizd]  	;# note the use of 'd' here instead of float, because of promotion rules
  > set p [malloc 64]
  > strcpy $p "Hello"
  > strcat $p " World!"
  > puts p=[ff::gets $p]
  p=Hello World!
  > proc test_1 {i z f} {
  >    puts "\ti=$i"
  >    puts "\tz=\"$z\""
  >    puts "\tf=$f"
  >    expr $i + 1
  > }
  > test_callback "message" $test_1
  begin test_callback message

<b>test_lib.c</b> - <i>test_lib.dll</i>
  typedef intptr_t (*callback_fn)();
  __declspec(dllexport) void test_callback( const char* msg, callback_fn callback) {
    printf("begin test_callback %s\n", msg);
    printf( "result=%d\n", callback( 1, "2", 3.0));
    printf( "end\n");
  __declspec(dllexport)  void* __malloc( size_t size) { return malloc(size); }
  __declspec(dllexport)  void __free( void* p) { free(p); }
  __declspec(dllexport) char* __strcpy( char* dst, const char* src) { return strcpy( dst, src); }
  __declspec(dllexport) char* __strcat( char* dst, const char* src) { return strcat( dst, src); }
Z 7ad9a74b3bf97e0b1a963b7d5f34d3ea