Skip to content

Conversation

@LeifAndersen
Copy link

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.

and

but only for the `generate-static-ffi` call. It doesn't make sense for
the mapped variant.
@jeapostrophe
Copy link

Neat, what does an example look like?

@LeifAndersen
Copy link
Author

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
Copy link
Author

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.

@jeapostrophe
Copy link

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

@LeifAndersen
Copy link
Author

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. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants