[Openmcl-devel] RDNZL in CCL: Exception occurred while executing foreign code
R. Matthew Emerson
rme at clozure.com
Fri Oct 16 20:39:32 PDT 2009
On Oct 16, 2009, at 5:28 PM, John Miller wrote:
> The problem looks to be one of passing the wrong type of argument.
> The C function I am calling is defined as
>
> void* invokeInstanceMember(const __wchar_t *methodName, void
> *target, int nargs, void *args[])
>
> h-to-ffi.sh interprets that to be
>
> (function ("/cygdrive/d/rdnzl-cpp-0.7.1/RDNZL/ffi-headers.h" 55)
> "invokeInstanceMember"
> (function
> ((pointer (unsigned-short ())) (pointer (void ())) (int ())
> (pointer (pointer (void ()))) )
> (pointer (void ()))) (extern))
>
> Then, given the following definitions:
>
> (defun %invoke-instance-member (method-name type nargs args)
> (ccl::with-native-utf-16-cstr (mn method-name)
> (#_invokeInstanceMember mn type nargs args)))
>
> (defun test-invoke-2 ()
> (let ((obj (make-type-from-name "System.Reflection.Assembly")))
> (%invoke-instance-member "ToString" (pointer obj) 0 (ccl:%null-
> ptr))))
>
> (defun test-invoke-3 ()
> (let ((obj (make-type-from-name "System.Reflection.Assembly"))
> (type (box* "System.Reflection.Assembly")))
> (ccl:rletz ((ptr (:array :address 1)))
> (setf (ccl:paref ptr (:array :address) 0) type)
> (%invoke-instance-member "GetType" (pointer obj) 1 ptr))))
>
> I call (test-invoke-2) and all is hunky-dorey, but I try (test-
> invoke-3) and all heck breaks loose. I have imagined, and tried a
> couple different ways of representing an array of pointers, but
> clearly I am not imaginative enough.
>
> It would be interesting to know if anyone else has tried calling
> foreign functions that have arguments of type void *args[]. I mean
> other than the code in cocoa-ide/start.lisp that I based the code in
> test-invoke-3 off of.
It seems to me that you're stack-allocating the array of pointers
correctly.
I would try running the lisp under gdb. Load the shared library that
contains
#_invokeInstanceMember, and then set a gdb breakpoint on it. Then
evaluate (test-invoke-3), and see if the arguments provided from lisp
look right.
Here's a trivial example I just came up with and ran on my Mac. (I
tried to do it on Windows, but I couldn't figure out at a quick glance
how to build a working dll with cygwin tools.)
#include <stdio.h>
void testing(char *name, void *target, int nargs, void *args[])
{
int i;
fprintf(stderr, "name = %s\n", name);
fprintf(stderr, "target = %p\n", target);
fprintf(stderr, "nargs = %d\n", nargs);
for (i = 0; i < nargs; i++)
fprintf(stderr, "args[%d] = %p\n", i, args[i]);
}
Compile that as a shared library, e.g., with cc -arch x86_64 -shared
ffi.c -o ffi.dylib or whatever the right thing is for your system.
Sorry to hand-wave like this.
With that in hand:
? (open-shared-library "ffi.dylib")
#<SHLIB ffi.dylib #x300041594C2D>
Now:
(defun testing ()
(rlet ((args (:array :address 3)))
(setf (paref args (:array :address) 0) (%int-to-ptr 9)
(paref args (:array :address) 1) (%int-to-ptr 99)
(paref args (:array :address) 2) (%int-to-ptr 999))
(with-cstrs ((s "hello"))
(external-call "testing" :address s :address (%null-ptr) :int 3
:address args :void))))
? (testing)
name = hello
target = 0x0
nargs = 3
args[0] = 0x9
args[1] = 0x63
args[2] = 0x3e7
I don't know if that helps or not.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.clozure.com/pipermail/openmcl-devel/attachments/20091016/b9f96bdb/attachment.htm>
More information about the Openmcl-devel
mailing list