Re: How to catch integer 64 bit return variable type

new topic     » goto parent     » topic index » view thread      » older message » newer message

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

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu