Data from a pointer to an array?

More fun with declares. I’m doing some stuff with libmodbus, reading from a register on a remote device. The register is a simple array: rows containing values. LibModbus has the following C function, which puts the data read from addr (the first register) to nb (the last register I want to read) into an array:

int modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest);

it returns the number of results as an integer, and the array in the pointer to dest. Apparently, I’m calling this correctly because it’s returning the right number of results and not throwing any errors. But I’m not really sure how to get dest into something usable in Xojo.

In my app:

Var readResults as ptr 
var read as integer = modbus_read_registers(mHandle, startReg, endReg, readResults)

In my app, modbus_read_registers is an external method I’m passing the parameters: mHandle as Ptr, startReg as Integer, endReg as Integer, byref readResults as ptr

So if I break after calling this function I can see there are results there, but of course, not human-readable. How can I get that into something useful? Ideally an array.

Likely you would look at the raw memory and parse it into an array yourself, something like this:

read = modbus_read_registers(..., readResults )

var data as MemoryBlock = readResults

var registers() as integer
for index as integer = 0 to read - 1
  data.Add mb.Int64Value( index * 8 )
next

Thanks. I think there are a couple typos in there: you mean

registers.add data.int64Value( index * 8)

inside the loop, I think, right?

anyway I made those changes and it segfaulted in the debugger. I have a few more minutes to play with this before I need to head out for the day but I’ll probably be able to look at it more on Monday. Thanks!

Yes, that’s what I meant. (I shouldn’t type code while I’m on a call. :slight_smile: )

1 Like

Can you post the code for your Declare?

So it’s not a direct declare statement exactly.

I mean, I’m doing this inside a class built in the Xojo IDE. You call my read_registers() method, which is where my code is. It calls the external method modbus_read_registers with all the info modbus_read_registers needs. Under the hood I’m sure that results in a declare statement, but I’m not sure how I would get that to post.

Where and how is that external method modbus_read_registers defined? Is this from some plugin or other “hidden” code?

In the Xojo GUI:

there’s a constant, LibModbus, that contains the path to the library. this references #LibModbus

Just tossing out ideas here…

Take off ByRef in that declaration. In your code, try something like this:

var data as new MemoryBlock( 8 * maxNumberOfRegisters )
read = modbus_read_registers( ..., data )

See what you get back in data, if anything.

ok, thanks. I’ll give that a try on Monday. Heading out for the weekend.

1 Like

Couldn’t resist - got my jacket on but I took out the byref and ran it. now it simply quits the debugger and drops me back into the IDE with no errors. app just vanishes. I’ll dig deeper next week

uint16_t is a UInt16 so it should probably be

registers.add data.UInt16Value( index * 2)

You also have to allocate the memory before you make the call, which is nb * 2 in size. So its probably something like (unchecked code)

var readResults as new memoryblock(endReg*2)
var read as integer = modbus_read_registers(mHandle, startReg, endReg, readResults)

var registers() as uint16
for index as integer = 0 to read - 1
  registers.add readResults.uint16value(index * 2)
next

and drop the byref from readResults as that will be a pointer to a pointer

1 Like

Hi Julian - thanks. this worked perfectly.

1 Like