From: Chisheng H. <cp...@ch...> - 2008-12-08 20:23:15
|
"Nikodemus Siivola" <nik...@ra...> writes: > On Mon, Dec 8, 2008 at 1:29 AM, Chisheng Huang <cp...@ch...> wrote: >> "Nikodemus Siivola" <nik...@ra...> writes: >> >>> On Sun, Dec 7, 2008 at 8:38 AM, Chisheng Huang <cp...@ch...> wrote: >>> >>>> With SBCL 1.0.22, RETURN-CODE is 0 on a Linux machine but >>>> -197853184 on a MS Windows machine. The correct value of >>>> RETURN-CODE on a MS Windows machine should be 0, which was >>>> confirmed by equivalent code for the MS Windows version of >>>> LispWorks. >>> >>> What does (DISASSEMBLE 'SQL-ALLOC-HANDLE) return for you on Windows, >>> and what on Linux? >> >> The combined output of DISASSEMBLE on Linux and on Windows is more than >> 600 lines. I put them here: >> http://chi-square-works.com/disassemble-linux >> http://chi-square-works.com/disassemble-windows > > Thanks. A once-over the Windows versions makes it look OK. Hi Nikodemus, Thanks a lot for taking time to check it out. > -197853184 has the same bits as #xF4350000 which baffles me a bit: the > low zeroes made me think maybe just need to look at the low bits only, > but > > http://msdn.microsoft.com/en-us/library/984x0h58(VS.71).aspx > > says that values are widened to 32 bits. > > What does > > int SQLAllocHandle(short, long*); > > void foo(void) { > long handle; > printf("#x%X\n", SQLAllocHandle(1, NULL, &handle); > } > > print for you on Windows? If you have a hard time getting it to link, Indeed, I had a hard time compiling it even after I modified it a bit. > the alternative is to call the function by loading the DLL and > function address dynamically (and casting the function pointer to the > same type as above). I did the following. Please let me know if it's what you suggested. (sb-alien:load-shared-object #+:win32 "odbc32.dll" #+:linux "libodbc.so") (use-package :sb-alien) (defun make-null-pointer () (sap-alien (sb-sys:int-sap 0) (* T))) (define-alien-type sql-handle (* t)) (define-alien-type sql-handle-ptr (* sql-handle)) ;; To get a SHORT return value from SQLAllocHandle... ;; The return value is -197853184 (or #x-BCB0000) ;; (with-alien ((g1035 sql-handle)) (let ((phenv (addr g1035))) (with-alien ((sql-alloc-handle (function short short sql-handle sql-handle-ptr) :extern "SQLAllocHandle")) (alien-funcall sql-alloc-handle 1 (make-null-pointer) phenv)))) ;; To get an INT return value from SQLAllocHandle... ;; The return value is 1949630464 (or #x74350000). ;; (with-alien ((g1035 sql-handle)) (let ((phenv (addr g1035))) (with-alien ((sql-alloc-handle (function int short sql-handle sql-handle-ptr) :extern "SQLAllocHandle")) (alien-funcall sql-alloc-handle 1 (make-null-pointer) phenv)))) I also used the MS Windows version of LispWorks to get a :INTEGER (equivalent to SB-ALIEN:INT) return value from SQLAllocHandle and this return value is also 1949630464 (or #x74350000). > At any rate, if my surmise is correct, and something funny is > happening with the short return value (and everything else is OK), you > should be able to work around this by using > > (ldb (byte 16 0) ...) I did another simple testing with no ODBC involved. 1. Create a C function: short ttmmpp () { int i = 17875817; return (short) i; } 2. After loading the DLL compiled from the above C function, the following 2 forms all return -15511, which is the same value as verified by a C printf. (sb-alien:with-alien ((ttmmpp (function sb-alien:int) :extern "ttmmpp")) (sb-alien:alien-funcall ttmmpp)) (sb-alien:with-alien ((ttmmpp (function sb-alien:short) :extern "ttmmpp")) (sb-alien:alien-funcall ttmmpp)) This simple test probably does not mean much as I have no idea what filler bits are used to widen return values to 32 bits by Microsoft. > as a wrapper around calls to functions returning shorts on Windows. > (It may be that we should do that anyways internally.) If what you guessed is true, may I suggest the wrapper to be added internally? Best wishes, -cph |