[Openmcl-devel] Problem with FFI on Win64

Gary Byers gb at clozure.com
Wed Oct 6 05:50:46 PDT 2010


This sounds like one of several bugs in the win64 FFI code that was fixed
in the trunk in <http://trac.clozure.com/ccl/changeset/14156>.  That change
wasn't propagated to the 1.5 sources, though I don't think that there's any
reason that it couldn't be.

Win64's calling conventions differ from those used on other x8664 platforms;
the differences have to do with how many arguments are passed in registers
and how floating-point and non-fp args are distributed between floating-point
and general-purpose registers.  For whatever reason, DEFCALLBACK on win64
seems to have gotten these details right, but FF-CALL was basically trying
to use the same conventions that other platforms use.

The change in r14156 does (as far as I can tell) fix your test case; I applied
the same changes to 1.5, verified that they seem to work, and committed them
to the 1.5 branch (as r14332.)

As far as I can tell, there's nothing wrong with your code; the code that
implements FF-CALL just wasn't putting the function's arguments in the right
places.

On Wed, 6 Oct 2010, Roman Marynchak wrote:

> Hello,
> ?I have a strange issue with a simple FFI example for CCL 1.5 ("Version
> 1.5-r13651 ?(WindowsX8664)") running on Win7 x64.
> 
> There is a dynamic library which exports this function:
> 
> extern "C" {
> SAMPLELIB_API int increment_array(double flag, unsigned short* array)
> {
> if (flag > 6.3) {
> array[0] = 83;
> array[1] += 2;
> array[2] += 7;
> array[3] = 61372;
> return 1;
> } else {
> array[0] = 726;
> array[1] += 111;
> array[2] += 222;
> array[3] = 888;
> return 2;
> }
> }
> }
> 
> 
> And the code below tries to invoke the foreign function:
> 
> (defun allocate-sample-array (required-length initial-value)
> ??(declare (type fixnum required-length))
> ??(declare (type (unsigned-byte 16) initial-value))
> ??(multiple-value-bind (array pointer)
> ?? ? ?(make-heap-ivector required-length '(unsigned-byte 16))
> ?? ?(loop for i from 0 below required-length do
> (setf (aref array i) initial-value))
> ?? ?(list array pointer)))
> 
> (defun do-test ()
> ??(let* ((lib (open-shared-library "D:\\SampleLib.dll"))
> (array-desc-pair (allocate-sample-array 4 1))
> (array (first array-desc-pair))
> (ptr (second array-desc-pair)))
> ?? ?(external-call "increment_array" :double-float 1.5d+2 :address ptr
> :integer)
> ?? ?(loop for element across array do (print element))
> ?? ?#|(close-shared-library lib)|#))
> 
> 
> DO_TEST crashes in EXTERNAL-CALL. Debugging with VS shows that
> increment_array is invoked, but the second argument is a null pointer. I
> guess that I have some issue in my code, but Ifollowed?http://openmcl.clozure.com/manual/chapter12.11.html#Tutorial--Allo
> cating-Foreign-Data-on-the-Lisp-Heap?while writing it. Could somebody please
> help me to understand what is wrong?
> 
> Also, CLOSE-SHARED-LIBRARY function seems to be absent in this CCL image. Is
> there any replacement for it?
> 
> 
> Thank you,
> Roman Marynchak?
> 
>



More information about the Openmcl-devel mailing list