dynamic-ffi icon indicating copy to clipboard operation
dynamic-ffi copied to clipboard

Add two additional flags:

Open LeifAndersen opened this issue 3 years ago • 5 comments

This is more or a proof of concept PR than something entirely fleshed out.

Add two additional flags:

#:named-structs

and

#:prefix-definitions

but only for the generate-static-ffi call. It doesn't make sense for the mapped variant.

LeifAndersen avatar Aug 10 '22 02:08 LeifAndersen

Neat, what does an example look like?

jeapostrophe avatar Aug 10 '22 08:08 jeapostrophe

As a small example, say you had the following header file:

typedef struct A {
  int x;
  int y;
} A;

typedef struct B {
  A u;
  int v;
} B;

And you built it with:

#lang racket

(require dynamic-ffi/unsafe)

(generate-static-ffi 'notalib "out.rkt" "libnotalib" 
       #:prefix-definitions? #f
       #:named-structs? #t
       "inc.h")

You end up with the generated file out.rkt:

#lang racket/base

(require ffi/unsafe)

(provide (all-defined-out))

(define notalib-ffi-lib (ffi-lib "libnotalib"))

(define notalib-headers (list "inc.h"))

(define ((warn-undefined-symbol sym))
  (eprintf "warning: notalib does not contain symbol ~a\n" sym))

(define-cstruct _A
  ((x _int32) (y _int32)))

(define-cstruct _B
  ((u (apply _list-struct (list _int32 _int32))) (v _int32))) 

There are two major downsides (that I'm aware of) right now:

  1. As you can see about nested structs, it still seems to fallback to the _list-struct definition. This can at least be mitigated by in your use composing make-A with A->list (generated by define-cstruct).
  2. If the ffi defines both: _structname and structname, which is sadly common giving _structname to the struct itself and structname to the typedef, then it generates:
(define-cstruct _structname ...)
(define-cstruct __structname ...)

This is a problem because of the name mangling that define-cstruct does. (It expects you to define _structname, but then it also defines structname in the same scope. I'm not sure how to best get around this.

P.S. I forgot to mention in the commit message, I added one additional thin in this PR, it derefs function pointers now, which greatly helps when importing an OOP C library...like CEF. https://github.com/cztomczak/cefcapi

LeifAndersen avatar Aug 10 '22 16:08 LeifAndersen

Oh, also, to address point 1, that would require using the LLVM/clang plugin to get struct field type names (instead of just their unqualified shapes), but I don't really know how to do that and don't have the bandwidth to look into it right now.

LeifAndersen avatar Aug 10 '22 16:08 LeifAndersen

Cool; I won't merge this, but maybe @dbenoit17 can give some advice or it will be a good checkpoint for future work

jeapostrophe avatar Aug 10 '22 16:08 jeapostrophe

Oh ya, sorry if that wasn't clear. I didn't open this PR because I think it should be merged as is. Its much more of a sketch that needs to be more fully fleshed out. :)

LeifAndersen avatar Aug 10 '22 16:08 LeifAndersen