LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Receiving pointer by reference from DLL

Solved!
Go to solution

Dear Labview heroes,

 

I have a working C++ script for communication with a sensor over Ethernet with a DLL that I am trying to repeat in Labview.

This is a snippet of the functioning C++ code:

 

Luc1234_0-1601377020190.png

The problem now is that 'data' is a pointer by reference to an array of uint8 and I do not know how that would work in Labview.

From what I read on the forums and the help, I need a call library block:

 

Capture.PNG

I have tried the following settings:

Capture2.PNG

It was suggested in a manual that this would work if I would leave the input empty and only wire the output, but this gives an error in the DLL function.

This is a link to the functions in the DLL: http://sch-remote.com/doc/SR01E12%20Library%20Functions.pdf

Other functions of the DLL are working in Labview, just the receiving of the pointer by reference is something that I have not figured out yet. 

 

Any help would be appreciated!

 

Best Regards,

 

Luc

 

 

 

0 Kudos
Message 1 of 26
(2,101 Views)
Solution
Accepted by topic author Luc1234

Minimum size should be one of the inputs.

 

Or use an init array with an size large enough, an use it as input.

0 Kudos
Message 2 of 26
(2,069 Views)

@Luc1234 wrote:

Dear Labview heroes,

 

I have a working C++ script for communication with a sensor over Ethernet with a DLL that I am trying to repeat in Labview.

This is a snippet of the functioning C++ code:

 

Luc1234_0-1601377020190.png

The problem now is that 'data' is a pointer by reference to an array of uint8 and I do not know how that would work in Labview.

From what I read on the forums and the help, I need a call library block:


Who told you that data must be a reference to a pointer? Nothing in this call syntax hints at that. Now if data is declared above this as

 

unsigned char **data;

 

Then you would be right but it is VERY unlikely that this is the case. 

 

Most likely it is simply declared as

 

usigned char data[8];

 

and then it is definitely NOT a reference to a pointer but simply a buffer pointer!

 

So show us more than this single line! We would also like to see the declaration of the data variable as well as the function prototype!

Rolf Kalbermatter
My Blog
0 Kudos
Message 3 of 26
(2,061 Views)

You are absolutely right, here is the code for the parameters used in sr_i2c_read_arr:

Luc1234_0-1601450775263.png

Luc1234_2-1601450837757.png

Luc1234_3-1601450859795.png

I know srh and address are correct in the Labview code, because other functions with the DLL are working correctly with these parameters.

 

Best Regards,

 

Luc

0 Kudos
Message 4 of 26
(2,034 Views)
Solution
Accepted by topic author Luc1234

Ok, let's look at this line by line:

 


@Luc1234 wrote:

You are absolutely right, here is the code for the parameters used in sr_i2c_read_arr:

Luc1234_0-1601450775263.png

Luc1234_2-1601450837757.png

Luc1234_3-1601450859795.png

I know srh and address are correct in the Labview code, because other functions with the DLL are working correctly with these parameters.

 

 

byte *data = new byte[8];

 

 

This declares a pointer variable named data, with the type byte. byte is not a standard C type but it is safe to assume that it is most likely defined/declared as unsigned char at some point in some header.

 

So this line is exactly equivalent in LabVIEW to an Initialize Array call with the type of uint8 and size 8.

 

Then some device opening and stuff which is quite unproblematic and then your much feared line:

 

 

int flag = sr_i2c_read_arrsrc, 0, address, data, 8);

 

 

As you can see the data pointer is passed directly to it, no reference operator or anything. It's simply the pointer itself.

And the function declaration almost certainly looks like:

 

 

int sr_i2c_read_arr(SR_HANDLE srh, someinteger somename, unsigned char adress, byte *data, int length); 

 

 

So declare this paramater as:

Type: Array

Constant: No

Subtype: (unsigned) 8-bit integer (depending if byte should be signed or unsigned)

Dimension: 1

Pass: Array Data Pointer

 

and wire that array you just initialized to te left hand side of that terminal, et voilà, full success! To make it clear that the size value in the according parameter (your last parameter in this function) is the same as the array size, I always use the same constant wired to both the Initialize Array and the according Call Library Node parameter. 

 

It is important that the caller provides buffers to C functions that this function is supposed to write data into. C does not know anything like managed code like .Net, which has clear rules about who needs to allocate memory and how. But C only has conventions. The most common convention is that the caller always has to provide any buffer that a function needs in its parameters. Yet LabVIEW can't do that for you automatically as it has absolutely no way of knowing how big that buffer should be. It could always allocate a 1MB buffer just to be safe and pass that anywhere, except it would be in 99% of the cases extremely wasteful and in the remaining 1% still not enough to not crash! The information about how big that buffer is is often contained in the function documentation (which LabVIEW can't read for you) or implicit depending on another parameter of the function (which LabVIEW can't know either without you telling it).

 

You could also instead of using an Initialize Array, define the size of the buffer in the Call Library node under

 

Minimum Size: .......

 

Here you can enter a number (for buffers that need to have a certain minimum size usually specified in the documentation) or select the name of one of the other parameters (if that parameter happens to indicate the number of array elements, which is not always the case. Sometimes an array is in a different datatype than bytes but the according size parameter to the function still requires the size to be specificed in bytes. In this case the number passed in the size parameter does not match the actual amount of array elements).

 

Personally I prefer to do the explicit Initialize Array call on the diagram to make the code more clear to the casual observer. The configuration setting in the Call Library Node requires one to open the configuration dialog to confirm that correct buffer allocation has been taken care of.

 

Rolf Kalbermatter
My Blog
Message 5 of 26
(2,007 Views)

Dear  

 

Now it looks as follows:

 

Capture.PNG

I wired the block like this:

Capture2.PNG

The code is executing but it returns all zeros in data and the function itself returns 0, which means failure.

Any other ideas?

 

Best Regards,

 

Luc 

 

0 Kudos
Message 6 of 26
(2,004 Views)

@Luc1234 wrote:

Capture2.PNG

The code is executing but it returns all zeros in data and the function itself returns 0, which means failure.

Any other ideas?

 


The Call Library Node call looks fine now. Is this 64-bit LabVIEW? In that case your SR_HANDLE may be not an uint32 but rather an uint64 instead! We can't know as you do keep showing only piecemeal information and always only in images. It's a lot easier to look through an actual header file or at a real LabVIEW diagram than trying to decipher things in an image.

Rolf Kalbermatter
My Blog
0 Kudos
Message 7 of 26
(1,999 Views)

Thank you for your reply.

 

The buffer is the 'minimum size' specification in the parameter settings?

The wiring would be correct like this?:

 

Luc1234_0-1601453249826.png

Because this code is executing, but the function itself returns 0 (not succesfull) and the data indicator is all zeros.

 

Best Regards,

 

Luc

0 Kudos
Message 8 of 26
(1,998 Views)

Thank you for your very fast reply, I was still replying myself.

You can find the vi in the attachment.

I know srh and address is correct because the other functions are executing correctly.

0 Kudos
Message 9 of 26
(1,995 Views)

Something in the parameters you pass to the function must be not right! What is not clear but it could be the value of the port variable, or some misinterpretation about your address. We can't tell you as we do not have the hardware to test.

 

If it was about the data pointer somehow, the function would not fail with an error. Instead it would go on happily to silently (or not so silently with a crash) corrupt memory and return success. So check the values of your parameters. Something with them is not right. To bad the function seems to only return a fail/success status and not a bit more of a detailed error status.

Rolf Kalbermatter
My Blog
0 Kudos
Message 10 of 26
(1,990 Views)