<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Oct 16, 2009, at 10:39 PM, R. Matthew Emerson wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Oct 16, 2009, at 5:28 PM, John Miller wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>The problem looks to be one of passing the wrong type of argument. The C function I am calling is defined as </div><div><br></div><div>void* invokeInstanceMember(const __wchar_t *methodName, void *target, int nargs, void *args[])</div><div><br></div><div>h-to-ffi.sh interprets that to be</div><div><br></div><div><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;">(function ("/cygdrive/d/rdnzl-cpp-0.7.1/RDNZL/ffi-headers.h" 55)<br> "invokeInstanceMember"<br> (function<br> ((pointer (unsigned-short ())) (pointer (void ())) (int ()) (pointer (pointer (void ()))) )<br> (pointer (void ()))) (extern))</span></font></div><div><br></div><div>Then, given the following definitions:</div><div><br></div><div><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;">(defun %invoke-instance-member (method-name type nargs args)<br> (ccl::with-native-utf-16-cstr (mn method-name)<br> (#_invokeInstanceMember mn type nargs args)))</span></font></div><div><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;"><br></span></font></div><div><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;">(defun test-invoke-2 ()<br> (let ((obj (make-type-from-name "System.Reflection.Assembly")))<br> (%invoke-instance-member "ToString" (pointer obj) 0 (ccl:%null-ptr))))<br><br>(defun test-invoke-3 ()<br> (let ((obj (make-type-from-name "System.Reflection.Assembly"))<br></span></font><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;"> </span></font></span><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;">(type (box* "System.Reflection.Assembly")))<br> (ccl:rletz ((ptr (:array :address 1)))<br> (setf (ccl:paref ptr (:array :address) 0) type)<br> (%invoke-instance-member "GetType" (pointer obj) 1 ptr))))</span></font></div><div><br></div><div>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.</div><div><br></div><div>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.</div></div></blockquote><div><br></div><div>It seems to me that you're stack-allocating the array of pointers correctly.</div><div><br></div><div>I would try running the lisp under gdb. Load the shared library that contains </div><div>#_invokeInstanceMember, and then set a gdb breakpoint on it. Then evaluate (test-invoke-3), and see if the arguments provided from lisp look right.</div><div><br></div><div>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.)</div><div><br></div><div><div><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;">#include <stdio.h></span></font></div><div><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;"><br></span></font></div><div><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;">void testing(char *name, void *target, int nargs, void *args[])</span></font></div><div><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;">{</span></font></div><div><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;"> int i;</span></font></div><div><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;"><br></span></font></div><div><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;"> fprintf(stderr, "name = %s\n", name);</span></font></div><div><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;"> fprintf(stderr, "target = %p\n", target);</span></font></div><div><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;"> fprintf(stderr, "nargs = %d\n", nargs);</span></font></div><div><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;"><br></span></font></div><div><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;"> for (i = 0; i < nargs; i++)</span></font></div><div><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;"> fprintf(stderr, "args[%d] = %p\n", i, args[i]);</span></font></div><div><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;">}</span></font></div><div><br></div></div><div>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.</div><div><br></div><div>With that in hand:</div><div><br></div><div>? (open-shared-library "ffi.dylib")</div><div>#<SHLIB ffi.dylib #x300041594C2D></div><div><br></div><div>Now:</div><div><br></div><div><div><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;">(defun testing ()</span></font></div><div><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;"> (rlet ((args (:array :address 3)))</span></font></div><div><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;"> (setf (paref args (:array :address) 0) (%int-to-ptr 9)</span></font></div><div><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;"> </span></font></span><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;"> (paref args (:array :address) 1) (%int-to-ptr 99)</span></font></div><div><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;"> </span></font></span><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;"> (paref args (:array :address) 2) (%int-to-ptr 999))</span></font></div><div><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;"> (with-cstrs ((s "hello"))</span></font></div><div><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;"> (external-call "testing" :address s :address (%null-ptr) :int 3 </span></font></div><div><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;"> </span></font></span><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;"> :address args :void))))</span></font></div><div><br></div><div>? (testing)</div><div><div>name = hello</div><div>target = 0x0</div><div>nargs = 3</div><div>args[0] = 0x9</div><div>args[1] = 0x63</div><div>args[2] = 0x3e7</div><div><br></div><div>I don't know if that helps or not.</div><div><br></div><div><br></div></div></div></div></div></blockquote></div><br><div>FYI, the incantation for creating a dll in mingw (installed as part of cygwin) is (wait for it):</div><div><br></div><div>gcc -mno-cygwin -shared test.c -o test.dll</div><div><br></div><div>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...</div><div><br></div><div>Thanks again,</div><div>John</div><div><br></div></body></html>