Re: How to catch integer 64 bit return variable type
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
|
Not Categorized, Please Help
|
|