[Openmcl-devel] RDNZL in CCL: Exception occurred while executing foreign code

John Miller millejoh at mac.com
Sat Oct 17 13:33:08 UTC 2009


On Oct 16, 2009, at 10:39 PM, R. Matthew Emerson wrote:

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

FYI, the incantation for creating a dll in mingw (installed as part of  
cygwin) is (wait for it):

gcc -mno-cygwin -shared test.c -o test.dll

And some more FYI:  I get the exact same results as you with the  
testing function defined above.  The thought of using GDB (Gary also  
mention WinDBG) is making me break out in a bit of a cold sweat, but I  
will try and see if I can make that work and get a little more info...

Thanks again,
John

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.clozure.com/pipermail/openmcl-devel/attachments/20091017/d1904e81/attachment.html>


More information about the Openmcl-devel mailing list