Author | Topic: Pointer to Pointer | |
---|---|---|
Simon Burford | Pointer to Pointer on Sun, 19 Jul 2009 23:00:58 +0100 Can anyone give me a simple piece of info regarding passing parameters to the API - I'm trying not to use third party libraries where possible simply to avoid nesting libraries in my own library and ending up with a product that relies on multiple libraries which may not all be available forever. So I really want actual XBase++ code rather than a call to an external interface to C in this case. I need to pass a pointer to a pointer to an API function. For example a C API function with this definition: SomeCFunc(INT32 nValue, char **pszStringData) I have no problem dereferencing pointers to pointers which are returned to me by the API, but how do I get a pointer to a pointer (**) using XBase++ code to pass in the DLLCall. IE: DLLCall("MyDll.dll", STD_CALL, "SomeCFunc", 123, WHAT GOES HERE?) Thanks in advance, Simon | |
Simon Burford | Re: Pointer to Pointer on Sun, 19 Jul 2009 23:04:41 +0100 By the way, I do have BAP linked into the project. Although most of the API calls and structure processing are now raw XBase++ code, BAP was used in some of the early code and is still linked in, so I'm more than happy to make calls to it if necessary to solve this pointer to pointer issue... Simon Burford wrote: > Can anyone give me a simple piece of info regarding passing parameters > to the API - I'm trying not to use third party libraries where possible > simply to avoid nesting libraries in my own library and ending up with a > product that relies on multiple libraries which may not all be available > forever. So I really want actual XBase++ code rather than a call to an > external interface to C in this case. > > I need to pass a pointer to a pointer to an API function. For example a > C API function with this definition: > > SomeCFunc(INT32 nValue, char **pszStringData) > > I have no problem dereferencing pointers to pointers which are returned > to me by the API, but how do I get a pointer to a pointer (**) using > XBase++ code to pass in the DLLCall. IE: > > DLLCall("MyDll.dll", STD_CALL, "SomeCFunc", 123, WHAT GOES HERE?) > > Thanks in advance, > > Simon | |
Pablo Botella | Re: Pointer to Pointer on Mon, 20 Jul 2009 21:43:52 +0200 Hi, Maybe you can use malloc() from the msvcrt.dll or GlobalAlloc() from kernel32 Regards, Pablo Botella | |
Pablo Botella | Re: Pointer to Pointer on Tue, 21 Jul 2009 15:47:43 +0200 >Maybe you can use malloc() from the msvcrt.dll or GlobalAlloc() from kernel32 I was asumed you need to provide the buffer but if that you want is retrieve a buffer local pBuffer := 0 DLLCall("MyDll.dll", STD_CALL, "SomeCFunc", 123, @pBuffer) and later get the bytes from the buffer | |
Simon Burford | Re: Pointer to Pointer on Tue, 21 Jul 2009 15:18:03 +0100 Hi Pablo, I was actually assuming it was more complex than it was. The DLL function returns a pointer to a pointer, so all I had to do was pass it a variable by reference (@nVar) - and when the DLL returns this variable holds the pointer to the data I want - then I just dereference it with BAP's StringOf(nVar). Works fine. I have another question that you can probably give me an answer to without even thinking about it How do I convert an 8 byte character string I've retrieved from the API which contains a 64 bit IEEE value into an XBase++ numeric? I have a function I've used before which I had thought did this but it obviously has a bug in it because it is returning values which are quite plainly stupid. If I ask the API for a number which I expect to be less than 10, and it returns a value like 472384947743849, I can tell something isn't right!!! So what's wrong with this function: FUNCTION Bin2Li(cInteger) /* Local variable declaration */ LOCAL nHigh, nLow, nRetVal /* Calculate Low and High portions of 64 Bit Integer */ nHigh:=Bin2u(Right(cInteger,4)) nLow:=Bin2u(Left(cInteger,4)) /* Calculate return value */ nRetVal:=Int(nLow+4294967296*nHigh) RETURN nRetVal Pablo Botella wrote: >> Maybe you can use malloc() from the msvcrt.dll or GlobalAlloc() from kernel32 > I was asumed you need to provide the buffer > but if that you want is retrieve a buffer > local pBuffer := 0 > DLLCall("MyDll.dll", STD_CALL, "SomeCFunc", 123, @pBuffer) > and later get the bytes from the buffer > | |
Pablo Botella | Re: Pointer to Pointer on Tue, 21 Jul 2009 16:53:45 +0200 Hi, > 64 bit IEEE value into an XBase++ numeric? is not a double? Bin2F( cBin ) Regards, Pablo | |
Simon Burford | Re: Pointer to Pointer on Tue, 21 Jul 2009 16:06:01 +0100 Oh my god, I didn't even know that function existed. How the heck did I miss that? I've always done it manually. The XBase++ manual must be too large lol Pablo Botella wrote: > Hi, > >> 64 bit IEEE value into an XBase++ numeric? > is not a double? > Bin2F( cBin ) > > Regards, > Pablo > > | |
Simon Burford | Re: Pointer to Pointer on Tue, 21 Jul 2009 16:20:57 +0100 Ok, just to be clear: Bin2f() returns an IEEE 64 bit floating point number, which is what I needed in this case and was the source of my confusion with my own function. On the other hand, my own function Bin2li() converts an 8 byte 64 bit buffer into a large integer. The distinction is that calling Bin2f() on the return value of, for example, the API High Resolution Timer function would return a value similar to 0.000000000000000 because it has been interpreted as a floating point number. Calling Bin2li() on the same return value would give you a long integer such as 4327832734834923... which is what you would be expecting. I've got so used to using Bin2li() to get long integers (LONGLONG) that I'd totally forgotten about Bin2f() Thanks Pablo Simon Simon Burford wrote: > Oh my god, I didn't even know that function existed. How the heck did I > miss that? I've always done it manually. The XBase++ manual must be too > large lol > > > > > Pablo Botella wrote: >> Hi, >> >>> 64 bit IEEE value into an XBase++ numeric? >> is not a double? >> Bin2F( cBin ) >> >> Regards, >> Pablo >> >> | |
Pablo Botella | Re: Pointer to Pointer on Tue, 21 Jul 2009 21:41:59 +0200 Hi, > Bin2f() returns an IEEE 64 bit floating point number, which is what I > needed in this case and was the source of my confusion with my own function. > On the other hand, my own function Bin2li() converts an 8 byte 64 bit > buffer into a large integer. Yes double and int64 have same size but content are totally unrelated http://www.xbwin.com/ot4xbXHlp/xbase_numeric_representation.html Your Bin2li() is perfect to get int64 nums Regards, Pablo Botella | |
Simon Burford | Re: Pointer to Pointer on Tue, 21 Jul 2009 16:22:11 +0100 Ok, just to be clear: Bin2f() returns an IEEE 64 bit floating point number, which is what I needed in this case and was the source of my confusion with my own function. On the other hand, my own function Bin2li() converts an 8 byte 64 bit buffer into a large integer. The distinction is that calling Bin2f() on the return value of, for example, the API High Resolution Timer function would return a value similar to 0.000000000000000 because it has been interpreted as a floating point number. Calling Bin2li() on the same return value would give you a long integer such as 4327832734834923... which is what you would be expecting. I've got so used to using Bin2li() to get long integers (LONGLONG) that I'd totally forgotten about Bin2f() Thanks Pablo Simon Simon Burford wrote: > Oh my god, I didn't even know that function existed. How the heck did I > miss that? I've always done it manually. The XBase++ manual must be too > large lol > > > > > Pablo Botella wrote: >> Hi, >> >>> 64 bit IEEE value into an XBase++ numeric? >> is not a double? >> Bin2F( cBin ) >> >> Regards, >> Pablo >> >> | |
Simon Burford | Re: Pointer to Pointer on Tue, 21 Jul 2009 16:23:26 +0100 Ok, just to be clear: Bin2f() returns an IEEE 64 bit floating point number, which is what I needed in this case and was the source of my confusion with my own function. On the other hand, my own function Bin2li() converts an 8 byte 64 bit buffer into a large integer. The distinction is that calling Bin2f() on the return value of, for example, the API High Resolution Timer function would return a value similar to 0.000000000000000 because it has been interpreted as a floating point number. Calling Bin2li() on the same return value would give you a long integer such as 4327832734834923... which is what you would be expecting. I've got so used to using Bin2li() to get long integers (LONGLONG) that I'd totally forgotten about Bin2f() Thanks Pablo Simon Simon Burford wrote: > Oh my god, I didn't even know that function existed. How the heck did I > miss that? I've always done it manually. The XBase++ manual must be too > large lol > > > > > Pablo Botella wrote: >> Hi, >> >>> 64 bit IEEE value into an XBase++ numeric? >> is not a double? >> Bin2F( cBin ) >> >> Regards, >> Pablo >> >> |