Page 1 of 1
Help wanted with a ⎕NA call
Posted: Wed May 17, 2017 3:39 pm
by ray
Hi,
I am trying to write a function to call a C function in a library using ⎕NA
This is what I have at present:
Code: Select all
ns NAi2cWriteByteData so
⍝ int i2cWriteByteData(unsigned handle,unsigned i2cReg,unsigned bVal)
⍝ This writes a single byte to the specified register of the device associated with handle.
⍝ handle:>=0,as returned by a call to i2cOpen
⍝ i2cReg:0-255,the register to write
⍝ bVal:0-0xFF,the value to write
⍝ Returns 0 if OK
ns.⎕NA'I ',so,'|i2cWriteByteData U U1 U1'
My problem is with the "unsigned bVal" which I have coded as "U1".
My code works when the value of bVal is between 0-127, but values between 128 and 255 are rejected by the C code at run time.
EG A bVal of 129 reports "bad bVal (-127)"
(Looks like a 2 compliment problem.)
Should I change the way I define bVal in the ⎕NA call, or how I assign values into bVal at run time?
Any suggestions?
Re: Help wanted with a ⎕NA call
Posted: Wed May 17, 2017 10:12 pm
by petermsiegel
See if this helps...
bVal is declared in C as an unsigned integer at the default width, typically 4-bytes (or 2-bytes, depending on the system), not 1-byte. So I'd expect you'd declare it as U (for the default width), not U1. Similarly for i2cReg.
C automatically (and obligatorily) promotes single-byte arguments to the default width, when pushing them onto the function call stack, as the receiving function expects. That function then chooses to ignore the "extra" C-generated bits beyond the first 8 as part of its semantics.
My recollection is that ⎕NA needs patterns like U1 for accessing packed objects, e.g. via structures or pointers/arrays.
Re: Help wanted with a ⎕NA call
Posted: Thu May 18, 2017 12:37 am
by ray
Thank you, replacing the "U1" by "U" works.
I had incorrectly assumed that because the value being written was a single byte, and the definition was "unsigned bVal", an unsigned integer of width one should provide the correct format.
Thank you once again.
Re: Help wanted with a ⎕NA call
Posted: Thu May 18, 2017 7:41 am
by Geoff|Dyalog
Hmm. U1 gives you range checking on the APL side. This feels more like a problem with sign extension as it goes from 1 byte to 4. I will log an issue. Since the work around is easy (whilst sacrificing range checking) it might not get high priority.
Re: Help wanted with a ⎕NA call
Posted: Fri May 19, 2017 6:33 am
by petermsiegel
Geoff / Ray,
Priority or not, I was curious. I tried testing a simple C routine that expected an unsigned (i.e. a 4-byte unsigned even if only one byte matters to the C program/mer), as in the standard declaration you (Ray) showed. The only difference was it reported to me what it saw.
When I did the ⎕NA with U1, the unsigned on the APL side (let's call that number UNS) came across to the C language side as a non-random garbage number, when UNS exceeded 127. (It was fine when unsigned at 127 or less.) This was the number, based on UNS:
4294967168 + 128|UNS -- when 128 ≤ UNS ≤ 255
UNS -- when UNS ≤ 127
4294967168 just happens to be this in binary:
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0
(7 zero bits, rather than 8). Looks like a mask for dealing with 7-bit ASCII...
If I then cut it back to 1 BYTE on the C size (UNS&0XFF), it was the correct number.
So, I think there IS a problem in how it handles unsigned numbers between 128 and 255, but since the routine on the other end REQUIRES a 4-byte unsigned, I'm still thinking U is the right pedagogical choice. But perhaps Dyalog APL protects the user beyond what is documented, by quietly extending short items (U1, U2, etc.) put on the call stack. That would be good to see documented (I couldn't find any examples demonstrating implicit expansion in the Lang Ref). Now I'm just curious.
In any case, as you (Geoff) noted, U always works-- no garbage in or out, albeit without APL doing any range checking for integer types.
Re: Help wanted with a ⎕NA call
Posted: Fri May 19, 2017 10:17 am
by Geoff|Dyalog
Peter:
Did you see that bit pattern with other values than 128? It still feels to me like a sign extension problem. Be patient - I will get to it. It is logged as issue 14591.
Re: Help wanted with a ⎕NA call
Posted: Sun May 21, 2017 4:09 am
by petermsiegel
Geoff|Dyalog wrote:Peter:
Did you see that bit pattern with other values than 128? It still feels to me like a sign extension problem. Be patient - I will get to it. It is logged as issue 14591.
Yep, I tried various numbers between 128 and 255 and it was the same EXACT pattern at least under MacOS.
Apologies for giving any impression of urgency-- I was only curious. I've satisfied myself that my ⎕NA calls avoid this problem (since I mask out unused bits on the C side).
Cheers