Re: How to catch integer 64 bit return variable type
- Posted by CChris <christian.cuvier at agriculture.gouv.fr> Jun 08, 2007
- 595 views
Juergen Luethje wrote: > > D. Darmawan wrote: > > > Thanks your quick response Juergen, > > > > I try to make my expectation more understandable. > > Assume that C function in API library is like this: > > > > }}} <eucode> > > long long int desired_function(any_struct_value*); > > </eucode> {{{ > > that will return any 64 bit integer value. > > > > Then I link and call that C function in my Eu code: > > > > }}} <eucode> > > myAPIfunc = define_c_func(myDLL, "desired_function", {C_POINTER}, C_LONG) > > > > x = c_func(myAPIfunc, {lpMyVar1}) > > </eucode> {{{ > > > > Now, my question is: > > How to catch the 64bit integer return value from myAPIfunc and assign it > > into > > 'x' variable??? > > I see. Unfortunately, for this case I don't have a solution. > However, if we declare the problem "insoluble", then Matt will solve it. :) > > Regards, > Juergen I didn't test this because I don't have functions that return 64-bit integers. However, it should work using inline assembly. As far as I know, 64-bit values are returned in EDX:EAX. So the idea is to write some assembly that will call the function and store EDX and EAX in known places you'll peek4u() on return.
constant asm64_wrapper={ 0,0,0,0, -- +0: address of function to call 0,0,0,0, -- +4: argument passed to it 0,0,0,0, -- +8: placeholder for EAX 0,0,0,0, -- +12:placeholder for EDX #FF,#35, -- +16:push dword mem 0,0,0,0, -- +18:patch with addr of second data dword #FF,#15, -- +22:call near dword 0,0,0,0, -- +24:patch with addr of 1st data dword #89,#D5, -- +28:mov dword [mem],EDX 0,0,0,0, -- +30:patch with addr of 4th dword #A3, -- +34:mov dword [mem],EAX 0,0,0,0, -- +35:patch with 3rd adr #C3 -- +39:ret near } constant wrapper_address = allocate(length(asm64_wrapper)) poke(wrapper_address,asm64_wrapper) -- patch position poke4(wrapper_address+18,wrapper_address+4) poke4(wrapper_address+24,wrapper_address) poke4(wrapper_address+30,wrapper_address+8) poke4(wrapper_address+35,wrapper_address+12) atom my_callback,my_arg my_callback = callback(myAPIfunc) my_arg = allocate(length_of_my_struct) poke(my_arg,my_struct) -- or whatever is more convenient, depending on the struct layout constant toHiDword = 65536*65536 -- 2^32 function get_longlongsigned(atom callback,atom arg) atom loDword,hiDword poke4(wrapper_address,callback) poke4(wrapper_address+4,arg) call(wrapper_address+16) -- code to exec starts there loDword=peek4u(wrapper_address+8) hiDword=peek4s(wrapper_address+12) return loDword + hiDword * toHiDword end function atom result result=get_longlongsigned(my_callback,my_arg)
Of course, variants of the asm64_wrapper sequence will have to be devised whenever the prototype changes. Change peek4s() to peek4u() to retrieve unsigned long longs. CChris