Subject: [clisp-list] Re: FFI questions about "C" unions

From: "Hoehle, Joerg-Cyril" <[email-masked]>
Date: Mon Dec 15 11:37:00 2003

Hi,

>> * John K. Hinsdale wrote:
>> I'm interfacing w/ a library (the Java "C" interface actually) that
>> uses a C "union" type.  E.g. to paraphrase its header file:

>> Now, I would like to pass these (and arrays of them) to and from my
>> Lisp and "C" code.  I know how to do this with structs: use say

There are short and very long answers. Let's see if the short one is enough.

An array of union types should be easier for in and out.

Please work with references (places), e.g. use c-pointer and with-foreign-* judiciously.

Consider ffi:slot
E.g.
  (ffi:slot (ffi:element my-place the-index) 'f) ;read/write as float

Does that already help or are you stumbling into a fundamental limitation?

>[...]and then you get Lisp accessors FOO-MEMBER1 defined.
>Is there some reason I cannot do this in CLISP?
Please submit a proposal (or implement) Lisp-level accessors.
How can they auto-detect the correct type?
IMHO, you'll have to write a wrapper that *knows* the correct type (gets it from somewhere) and returns/sets data based on that. That looks like case by case work, which doesn't mean there couldn't be a declarative approach for some common cases.

Regards,
	Jorg Hohle.

---

From: "John K. Hinsdale" <[email-masked]>
Date: Mon Dec 15 11:56:02 2003

> An array of union types should be easier for in and out.

as it happens my C lib's interface uses arrays of unions

 > with-foreign-* judiciously.

I'll try :)

 > How can they auto-detect the correct type?

Well, if I have, in C

  union foo { ival int; dval double; };

then lisp will know which type to use because "ival" is an int and
"dval" is a double.  So accessor FOO-IVAL will know its an int
due to the definition.

 > IMHO, you'll have to write a wrapper that *knows* the correct type
 > (gets it from somewhere) and returns/sets data based on that.

it's specified in the union declaration just as with a struct.

I reiterate my question: why should it be any different than a struct
which in "C" languages is syntactically exactly the same as as a
union, except for the fact that only one of the members can be set per
instance of it (i.e., they "overlap").

At any rate, I've got another way to get around it: I can make a
two-element struct

   struct my_union { char type; void * val };

which encodes which union member is set in the type, and passes the
value as an opaque pointer (cast appropriately to point to the correct
type on the "C" side), and then use that to set up the union that my
library wants to see.  A bit clunky, and yes I know I should avoid
void * but it will get me up and running.

[Background: I'm trying to access some Java classes from Lisp.  I know
about JaCol but for various reasons I want to load the java runtime
("VM") directly into my CLISP process using the Java "C" API.  JaCol
has a "looser" coupling and requires external client/processes]