[Openmcl-devel] Foreign function calls
Gary Byers
gb at clozure.com
Thu Jul 1 02:21:57 PDT 2004
On Thu, 1 Jul 2004, Andrew P. Lentvorski, Jr. wrote:
> Can anybody point me at some examples for the foreign function
> interface?
>
> What I'm trying to do is to call a C function with a signature of
>
> void gtk_init(int *argv, char **argc);
It's usually the other way around: "argc" is conventionally an integer
argument count (or a pointer to one) and argv is a pointer to one or
more "pointers to char" (C strings).
>
> I can open the library and dereference the function. After going over
> the both the new and old docs, I can't figure out how to convert the
> OpenMCL fixnum into a C integer and then take the reference of it in
> order to pass its pointer into the function.
>
RLET can be used to create temporary "dynamic-extent" pointers to foreign
objects.
(rlet ((var typeI)) &body body)
executes BODY in an environment in which each VAR is bound to a temporary
(stack-allocated) pointer to an instance of the corresponding foreign type.
In
(rlet ((foo :int))
...)
FOO is a pointer to a C "int" (which happens not to have a
well-defined initial value). The effect of this is something like
that of the C code fragment:
int _foo, *foo = &_foo;
with one important difference being that the int that the lisp code points
to isn't named.
(rlet ((foo :int 1))
...)
is similar, only the integer value that FOO points to is initialized to
1 in this case.
> I also don't see how to allocate the strings so that I can dereference
> it twice.
(WITH-CSTRS ((c-string-ptr lisp-string-expression)*) ...)
has the effect of copying the characters in the lisp string to a null-
terminated, stack-allocated block of memory and binding the corresponding
c-string-ptr to a pointer to that block of memory; "c-string-ptr" is
effectively equivalent to a C "char *" pointer. If you want a pointer to
that pointer (a char **), you basically have to put the char * someplace:
(with-cstrs ((arg "Hello"))
(rlet ((argv (:* (:* :char)) char-star))
...))
has the effect of binding ARGV to a pointer to a pointer to a null-terminated
sequence of characters.
For no particularly good reason, PREF (and (SETF PREF)) don't offer
convenient syntax for dealing with foreign arrays, and it's often
necessary to use lower-level primitives and do address arithmetic by
hand. (Having a macro expand into code that does that address
arithmetic for you isn't rocket science, but it's never been
implemented in OpenMCL.) Functions that take a "pointer to pointer to
char" argument (like #_gtk_init and #_main and the #_exec functions)
often expect that pointer to point to a null-terminated sequence of
character pointers. There's a fairly scary-looking function in the
OpenMCL sources called CCL::CALL-WITH-STRING-VECTOR; it's used to
create an "argv"-like foreign vector from a set of lisp strings, and
is used in the guts of RUN-PROGRAM and (IIRC) to call #_gtk_init in
some of the (old) Linux gtk+ examples in the "ccl:examples;"
directory.
>
> Thanks for any help.
>
> -a
>
> _______________________________________________
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
> http://clozure.com/mailman/listinfo/openmcl-devel
>
>
More information about the Openmcl-devel
mailing list