Help wanted with a ⎕NA call

No need to worry about going "off topic" here
Forum rules
This forum is for general chit-chat, not necessarily APL-related. However, it's not for spam or for offensive or illegal comments.

Help wanted with a ⎕NA call

Postby ray on Wed May 17, 2017 3:39 pm

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?
Ray Cannon
Please excuse any smelling pisstakes.
User avatar
ray
 
Posts: 217
Joined: Wed Feb 24, 2010 12:24 am
Location: Blackwater, Camberley. UK

Re: Help wanted with a ⎕NA call

Postby petermsiegel on Wed May 17, 2017 10:12 pm

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.
petermsiegel
 
Posts: 140
Joined: Thu Nov 11, 2010 11:04 pm

Re: Help wanted with a ⎕NA call

Postby ray on Thu May 18, 2017 12:37 am

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.
Ray Cannon
Please excuse any smelling pisstakes.
User avatar
ray
 
Posts: 217
Joined: Wed Feb 24, 2010 12:24 am
Location: Blackwater, Camberley. UK

Re: Help wanted with a ⎕NA call

Postby Geoff|Dyalog on Thu May 18, 2017 7:41 am

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.
Geoff|Dyalog
 
Posts: 43
Joined: Wed May 13, 2009 12:36 pm

Re: Help wanted with a ⎕NA call

Postby petermsiegel on Fri May 19, 2017 6:33 am

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.
petermsiegel
 
Posts: 140
Joined: Thu Nov 11, 2010 11:04 pm

Re: Help wanted with a ⎕NA call

Postby Geoff|Dyalog on Fri May 19, 2017 10:17 am

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.
Geoff|Dyalog
 
Posts: 43
Joined: Wed May 13, 2009 12:36 pm

Re: Help wanted with a ⎕NA call

Postby petermsiegel on Sun May 21, 2017 4:09 am

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
petermsiegel
 
Posts: 140
Joined: Thu Nov 11, 2010 11:04 pm


Return to Chat

Who is online

Users browsing this forum: No registered users and 1 guest