Alaska Software Inc. - Pointer to Pointer
Username: Password:
AuthorTopic: 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 BotellaRe: 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 BotellaRe: 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 BotellaRe: 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 BotellaRe: 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
>>
>>