Re: How to catch integer 64 bit return variable type
- Posted by D. Darmawan <skeydon_id at yahoo.co.id> Jun 16, 2007
- 605 views
Thanks Chris, Matt and Juergen, I able to catch integer 64 bit return value now. It's solved. I use Matt's fptr.e and made a little modification on call_cdcel function. It's working on Linux and I've not tested this modification on Windows yet. Here is the modified code on fptr.e I've made: </eucode> {{{ constant fptr_cdecl_asm = { #60, -- 0: pusha #BB,#00,#00,#00,#00, -- 1: mov ebx, paramcount (2) #B9,#00,#00,#00,#00, -- 6: mov ecx, params (7) -- B: start: #8B,#01, -- B: mov eax, [ecx] #50, -- D: push eax #83,#C1,#04, -- E: add ecx, 4 #4B, -- 11: dec ebx #75,#F7, -- 12: jnz start #FF,#15,#00,#00,#00,#00, -- 14: call dword ptr [comfunc] (22) #A3,#00,#00,#00,#00, -- 1A: mov [retpointer], eax (27) #89,#15,#00,#00,#00,#00, -- 1F: mov [retpointer], edx (33) --- additional bytecode #83, #C4, 00, -- 25: add esp 0 (39 or #27) #61, -- 28: popa #C3}, -- 29: ret fptr_cdecl_paramcount = 2, fptr_cdecl_params = 7, fptr_cdecl_funcptr = 22, fptr_cdecl_retptrLo = 27, --- fptr_cdecl_retptr fptr_cdecl_retptrHi = 33, --- additional new pointer cdecl_retval = allocate(4), fptr_cdecl_asm_addr = allocate( length( fptr_cdecl_asm ) + 20 * 4 ) constant --- changed from #24 to #2A fptr_cdecl_func = fptr_cdecl_asm_addr + #2A, fptr_cdecl_retvalLo = fptr_cdecl_asm_addr + #2A + 4, fptr_cdecl_retvalHi = fptr_cdecl_asm_addr + #2A + 8, --- insert new pointer for edx value fptr_cdecl_param_ptr = fptr_cdecl_asm_addr + #2A + 12 --- changed from #24 + 8 poke( fptr_cdecl_asm_addr, fptr_cdecl_asm ) poke4( fptr_cdecl_asm_addr + fptr_cdecl_funcptr, fptr_cdecl_func ) poke4( fptr_cdecl_asm_addr + fptr_cdecl_params, fptr_cdecl_param_ptr ) poke4( fptr_cdecl_asm_addr + fptr_cdecl_retptrLo, fptr_cdecl_retvalLo ) poke4( fptr_cdecl_asm_addr + fptr_cdecl_retptrHi, fptr_cdecl_retvalHi ) --- additional line --/topic Calling functions --/func call_cdecl( atom fptr, sequence params ) --/ret Return value of fptr --/desc Calls a function using cdecl --Calls a function using stdcall --Use this to call a function using the stdcall calling convention when you --have a pointer to the function. This is the most common calling convention in --Linux. You can get the pointer to a function in a --.dll or .so using /b define_c_var() instead of /b define_c_func(). You should --discard the return value if you call a routine that does not return a value. global function call_cdecl( atom fptr, sequence params ) atom ret -- store the pointer to the function poke4( fptr_cdecl_func, fptr ) -- reverse the params for stdcall calling convention params = reverse(params) -- store the params poke4( fptr_cdecl_param_ptr, params ) -- tell the asm how many params to push/pop poke4( fptr_cdecl_asm_addr + fptr_cdecl_paramcount, length(params) ) poke( fptr_cdecl_asm_addr + #27, length(params) * 4) --- changed #21 to #27 -- run the asm call( fptr_cdecl_asm_addr ) -- get the value returned from the function ret = peek4u( fptr_cdecl_retvalLo ) + peek4s( fptr_cdecl_retvalHi ) * #100000000 -- modified return ret end function </eucode> {{{ And sqlite3 wrapper has been modified to:
include fptr.e --- --- global function sqlite_column_int(atom db, atom stmt, integer column_num) integer ptr ptr = define_c_var(sqlite3_dll, "sqlite3_column_int64") return call_cdecl(ptr, {stmt, column_num - 1 }) end function
Regards, Doni