1. How to catch integer 64 bit return variable type
- Posted by "D. Darmawan" <skeydon_id at yahoo.co.id> Jun 08, 2007
- 670 views
Dear all, I'm building a small application using sqlite3 API. The application run smoothly until an integer field consists a value greater than 32 bit integer was found on database. Particularly, sqlite3 API has some functions with 64 bit integer return value (long long int variable type), but it can't be catch properly in Euphoria since library dll.e does not provide any constant variable for handling 64 bit integer return value at all. Trying one of both C_FLOAT and C_DOUBLE only return a 'nan' value. Any information, suggestion or an idea to solve this problem? PS: Sorry for my bad english.... Doni
2. Re: How to catch integer 64 bit return variable type
- Posted by Juergen Luethje <j.lue at gmx.de> Jun 08, 2007
- 598 views
D. Darmawan wrote: > Dear all, > > I'm building a small application using sqlite3 API. The application run > smoothly until an integer field consists a value greater than 32 bit > integer was found on database. Particularly, sqlite3 API has some > functions with 64 bit integer return value (long long int variable > type), but it can't be catch properly in Euphoria since library dll.e > does not provide any constant variable for handling 64 bit integer > return value at all. Trying one of both C_FLOAT and C_DOUBLE only return > a 'nan' value. > > Any information, suggestion or an idea to solve this problem? You need functions like these:
global function peek8u (atom addr) -- returns an *unsigned* 8-byte integer return peek4u(addr+4)*#100000000 + peek4u(addr) end function global function peek8s (atom addr) -- returns a *signed* 8-byte integer atom ret ret = peek4u(addr+4)*#100000000 + peek4u(addr) if ret > #7FFFFFFFFFFFFFFF then ret -= #10000000000000000 end if return ret end function
-- Then in your program use code such as:
myAPIfunc = define_c_func(myDLL, "desired_function", {C_POINTER, C_POINTER}, C_LONG) lpMyVar1 = allocate(8) lpMyVar2 = allocate(8) x = c_func(myAPIfunc, {lpMyVar1, lpMyVar2}) myVar1 = peek8u(lpMyVar1) myVar2 = peek8s(lpMyVar2) free(lpMyVar1) free(lpMyVar2)
Regards, Juergen
3. Re: How to catch integer 64 bit return variable type
- Posted by D. Darmawan <skeydon_id at yahoo.co.id> Jun 08, 2007
- 633 views
Thanks your quick response Juergen, I try to make my expectation more understandable. Assume that C function in API library is like this:
long long int desired_function(any_struct_value*);
that will return any 64 bit integer value. Then I link and call that C function in my Eu code:
myAPIfunc = define_c_func(myDLL, "desired_function", {C_POINTER}, C_LONG) x = c_func(myAPIfunc, {lpMyVar1})
Now, my question is: How to catch the 64bit integer return value from myAPIfunc and assign it into 'x' variable??? Doni
4. Re: How to catch integer 64 bit return variable type
- Posted by Juergen Luethje <j.lue at gmx.de> Jun 08, 2007
- 616 views
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
5. Re: How to catch integer 64 bit return variable type
- Posted by CChris <christian.cuvier at agriculture.gouv.fr> Jun 08, 2007
- 616 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
6. Re: How to catch integer 64 bit return variable type
- Posted by Matt Lewis <matthewwalkerlewis at gmail.com> Jun 08, 2007
- 617 views
Juergen Luethje wrote: > > D. Darmawan wrote:
myAPIfunc = define_c_func(myDLL, "desired_function", {C_POINTER}, C_LONG) x = c_func(myAPIfunc, {lpMyVar1})
> > > > 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. :) Sure, no pressure, right? :) My solution would be to either write a wrapper dll, or to call the dll with something along the lines of fptr.e. With either method, I'd return the value to a memory buffer that would be read by something like Juergen's peek8 routine. So a C-based wrapper function might look something like: void myAPIfuncWrapper( long long * retval, int * api_param ){ *retval = myAPIfunc(api_param); } I found this: http://www.ecos.sourceware.org/ml/gdb/2000-q1/msg00660.html 2. As far as I can tell, all i386 targets return `long long' values in eax (low word) and edx (high word). This makes sense since this is the convention used by the machine instructions themselves. The relevant GCC code suggests that in addition to eax and edx, ecx might also be used for 12-byte values (then edx is the "middle" word, and ecx the high word). But since GCC doesn't have a 12-byte integer type (would that make sense?) this should never occur. However, the full 12-byte range is used for returning extended floating-point numbers (`long double'). Right now this is only implemented for AIX, Linux and DJGPP, but this should be made more general. Matt
7. Re: How to catch integer 64 bit return variable type
- Posted by D. Darmawan <skeydon_id at yahoo.co.id> Jun 08, 2007
- 606 views
CChris wrote: > > 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. > }}} <eucode> > 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) > </eucode> {{{ > > 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 Thanks for your idea Chris... I'll try it first... Regards Doni
8. Re: How to catch integer 64 bit return variable type
- Posted by Juergen Luethje <j.lue at gmx.de> Jun 08, 2007
- 630 views
Matt Lewis wrote: > Juergen Luethje wrote: <snip> >> However, if we declare the problem "insoluble", then Matt will solve it. :) > > Sure, no pressure, right? :) <snip> Hi Matt, I didn't want to put you under pressure. If my post lokked like that or had such a side effect, then I'm really sorry. Regards, Juergen
9. Re: How to catch integer 64 bit return variable type
- Posted by ChrisBurch2 <crylex at freeuk.co.uk> Jun 08, 2007
- 603 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 Hi This is interesting. Are you using the sqlite3 wrappers? Are you trying to get a large signed integer from a database query, or as a return value from one of the other functions? The reason I ask is that database queries are returned as text values in sqlite3, so you have to do the conversion afterwards. However, if you are using functions not yet wrapped in eusqlite3, and you do manage to wrap them, I would be more than happy to add them to eusqlite3 library. Chris
10. Re: How to catch integer 64 bit return variable type
- Posted by Juergen Luethje <j.lue at gmx.de> Jun 08, 2007
- 600 views
ChrisBurch2 wrote: > 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 > > > Hi > > This is interesting. > > Are you using the sqlite3 wrappers? No, I don't do so. I probably expressed myself somewhat unclear. > Are you trying to get a large signed integer from a database query, or as > a return value from one of the other functions? As far as I can see, the peek8u() and peek8s() functions that I posted are only useful when a parameter of a sqlite function is a _pointer_ to a 64-bit integer. Is this sometimes the case? > The reason I ask is that database queries are returned as text values in > sqlite3, > so you have to do the conversion afterwards. > > However, if you are using functions not yet wrapped in eusqlite3, and you do > manage to wrap them, I would be more than happy to add them to eusqlite3 > library. Unfortunately, I almost don't know anything about sqlite. Regards, Juergen
11. Re: How to catch integer 64 bit return variable type
- Posted by Matt Lewis <matthewwalkerlewis at gmail.com> Jun 09, 2007
- 591 views
Juergen Luethje wrote: > > Matt Lewis wrote: > > > Juergen Luethje wrote: > > <snip> > > >> However, if we declare the problem "insoluble", then Matt will solve it. :) > > > > Sure, no pressure, right? :) > > <snip> > > Hi Matt, > > I didn't want to put you under pressure. If my post lokked > like that or had such a side effect, then I'm really sorry. No, of course not. I was flattered, really. :) Matt
12. Re: How to catch integer 64 bit return variable type
- Posted by D. Darmawan <skeydon_id at yahoo.co.id> Jun 12, 2007
- 657 views
ChrisBurch2 wrote: > > Hi > > This is interesting. > > Are you using the sqlite3 wrappers? > Are you trying to get a large signed integer from a database query, or as > a return value from one of the other functions? Yes Chris, I'm using sqlite3 wrapper, and the problem was occurred when I'm trying to get a large signed integer in one numeric field from a database query > The reason I ask is that database queries are returned as text values in > sqlite3, > so you have to do the conversion afterwards. Really??? FYI, I performed sqlite_step and sqlite_column_int that will return an integer value from certain field. I think what you're talking about sqlite_get_table function. Yes, I know that function will return text value and we can pointing it out with data[row][col] in sequence format. But it's memory greedy while it's returning a huge rowset. > However, if you are using functions not yet wrapped in eusqlite3, and you do > manage to wrap them, I would be more than happy to add them to eusqlite3 > library. > > Chris I'd love too, Chris. That is a great idea. Ability to returning value in big integer from some functions may be placed in first priority, I think. And then, making some functions for handling query function customization is a good idea (I've written this one in my modified eusqlite3 wrapper). Regards, Doni
13. Re: How to catch integer 64 bit return variable type
- Posted by ChrisBurch2 <crylex at freeuk.co.uk> Jun 12, 2007
- 613 views
D. Darmawan wrote: > > ChrisBurch2 wrote: > > > > Hi > > > > This is interesting. > > > > Are you using the sqlite3 wrappers? > > Are you trying to get a large signed integer from a database query, or as > > a return value from one of the other functions? > > Yes Chris, I'm using sqlite3 wrapper, and the problem was occurred when I'm > trying > to get a large signed integer in one numeric field from a database query > > > The reason I ask is that database queries are returned as text values in > > sqlite3, > > so you have to do the conversion afterwards. > > Really??? FYI, I performed sqlite_step and sqlite_column_int that will return > an > integer value from certain field. Yes, you're right. I've never used, or needed to use those functions in the wrapper, a clear case of disuse atrophy. > I think what you're talking about sqlite_get_table function. Yes, I know that > function > will return text value and we can pointing it out with data[row][col] in > sequence format. But it's memory greedy while it's returning a huge rowset. > > > However, if you are using functions not yet wrapped in eusqlite3, and you do > > manage to wrap them, I would be more than happy to add them to eusqlite3 > > library. > > > > Chris > > I'd love too, Chris. That is a great idea. Ability to returning value in big > integer > from some functions may be placed in first priority, I think. And then, making > some > functions for handling query function customization is a good idea (I've > written > this > one in my modified eusqlite3 wrapper). > Are you able now to have 64 bit integers returned from sqlite_column_int calls? And, will the same function return lower vaue (smaller bit count) integers? If you are amenable, I would like to take a look at your modified functions, for incorporation into the wrapper. post to crylex at gmail dot com > Regards, > Doni Cheers Chris
14. Re: How to catch integer 64 bit return variable type
- Posted by D. Darmawan <skeydon_id at yahoo.co.id> Jun 16, 2007
- 599 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
15. Re: How to catch integer 64 bit return variable type
- Posted by Juergen Luethje <j.lue at gmx.de> Jun 16, 2007
- 598 views
D. Darmawan wrote: > 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. [code snipped] This is good news. Especially, since in general the 64-bit stuff will become more and more important. Regards, Juergen