[Gambas-user] unsigned int datatype for external function

ML d4t4full at gmail.com
Mon Jun 11 16:17:02 CEST 2018


*On 11/06/18 10:46, Benoît Minisini wrote:*
> *Le 11/06/2018 à 15:40, T Lee Davidson a écrit : *
>> It's not that I didn't believe you, Jussi. Hence, the reason I asked
>> the question regarding how to handle a 32-bit integer
>> stored in a 31+1 integer datatype. A question that you have now
>> partially answered by example using Bin$().
>>
>>> Private Extern TakeAndReturn(value As Long) As Long In "liblibTest"
>>
>> It doesn't make any sense to pass a long to a function that is
>> expecting 32-bit integer. And, of course, the function would not
>> treat the most significant bit as a sign bit. So, passing a signed
>> integer TO the function is no problem. But when receiving the
>> return value FROM the function, it would be stored in a signed
>> integer datatype. So then back to my question, how to handle an
>> unsigned integer in a signed integer datatype?
>> Why not do:
>> Private Extern TakeAndReturn(value As Integer) As Long In "liblibTest"
>
> See my answer in the same thred.

Pardon me butting in...

I learned one or two things from interfacing VB6 with the Windows API.
I guess that, since both OS's run (OK, one runs, the other crawls) on
the same common architecture (x86) the concepts are really the same.

The Gambas Integer (32bit) and C int (also 32bit) are the plain same.
What changes is the INTERPRETATION each language gives these 4 bytes.
C sees the full 32bit as a positive integer ranging 0 to +4Gigs. Gambas
(and VB6...) see these same 32bit as a signed integer ranging -2Gigs to
+2Gigs.
Range "extension" in both cases is the same 4Gigs, simply because that's
what you get in 32bit! Only the "zero" is shifted.

Plain C cannot make heads nor tails with a negative integer, whereas
Gambas/VB6 explodes if it tries to shove a value over +2Gig on a 32bit
integer.
(purists could say the negative range is larger than the positive range
by one; that would be the ZERO taking a place in the positive range)

Why? Simple: Gambas uses two's complement to interpret 32bit data as a
signed integer (https://en.wikipedia.org/wiki/Two%27s_complement).
C, on the other hand, simply adds bit weights and spits back a positive
integer.

This is actually the reason why some error codes that have bit 31 set
(the most significant bit) make some languages emit a (very big)
NEGATIVE error number; these codes are being interpreted in two's
complement.

Hope I make the matter clearer; the Wiki page also has an example short
3bit table in two's complement to help the reader see the overall method.

The real problem:
If you DIM in Gambas an EXTERN C 32 bit int as LONG chances are
segfaults, etc. because you're actually pushing 8 bytes instead of 4
bytes to the stack, and the C function expects 4 bytes...
Depending on what the EXTERN C code does this abomination can pass
unnoticed... or it can make things really go down the drain.
You MUST ALWAYS pass as many bytes as the EXTERN function needs. No
more, no less.
Doing this properly includes understanding what the function expects,
and that involves knowing at least a little C.
Pointers will haunt you. Be warned. Mbwehehehe!!! *flaps cape and
dissappears in a surreal Z80 mist*

Regards,
zxMarce
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.gambas-basic.org/pipermail/user/attachments/20180611/d5181774/attachment-0001.html>


More information about the User mailing list