<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">Well, I may not be too savvy to use gdb or WinDBG, but I can download Visual Studio C++ Express and write lots of fprintf statements.  The array of pointers is not the problem.  In fact argument passing is not the problem.  The problem is that the method I am calling in the code below ("GetType") is not defined for the .Net class System.Type, which is what is returned when I call make-type-from-name.<div><br></div><div>In the managed C++ code when that happens it tries to throw an exception via the following code:</div><div><br></div><div><div><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;">   String ^msg = String::Concat(</span></font></div><div><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;">                                (int)(BindingFlags::Static & bindingAttr) ? "Static method not found: " : "Instance method not found: ",</span></font></div><div><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;">                                type->FullName,</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;">                                gcnew String(methodName)</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;">   msg = String::Concat(msg, "(");</span></font></div><div><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;">   for (int i = 0; i < argTypes->Length; i++) {</span></font></div><div><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;">     if (i)</span></font></div><div><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;">       msg = String::Concat(msg, ",");</span></font></div><div><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;">     msg = String::Concat(msg, argTypes[i]->FullName);</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;">   msg = String::Concat(msg, ")");</span></font></div><div><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;">   fprintf(stderr,"%s\n",msg);</span></font></div><div><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;">   throw gcnew Exception (msg);</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;"><span class="Apple-style-span" style="font-family: Helvetica; font-size: medium; ">I can see the error message printed by the fprintf statement, but when it tries to do "</span>throw gcnew Exception(msg);<span class="Apple-style-span" style="font-family: Helvetica; font-size: medium; ">"  Why is throw causing a machine level exception to occur?</span></span></font></div><div><br></div><div>Thanks,</div><div>John</div><div><br></div><div><div>On Oct 17, 2009, at 8:33 AM, 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; "><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></div>_______________________________________________<br>Openmcl-devel mailing list<br><a href="mailto:Openmcl-devel@clozure.com">Openmcl-devel@clozure.com</a><br>http://clozure.com/mailman/listinfo/openmcl-devel<br></blockquote></div><br></div></body></html>