LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Passing an array in Call library

That most likely is wrong!

 

What you should have instead:

 

function(....., BYTE array1byte1,  BYTE array1byte2, BYTE array1byte3, BYTE array1byte4, BYTE array1byte5, BYTE array1byte6, BYTE array2byte1, BYTE array2byte2, BYTE array2byte3, BYTE array2byte4, BYTE array2byte5, BYTE array2byte6, BYTE array3byte1, BYTE array3byte2, BYTE array3byte3, BYTE array3byte4, BYTE array3byte5, BYTE array3byte6, BYTE array4byte1, BYTE array4byte2, BYTE array4byte3, BYTE array4byte4, BYTE array4byte5, BYTE array4byte6, BYTE array5byte1, BYTE array5byte2, BYTE array5byte3, BYTE array5byte4, BYTE array5byte5, BYTE array5byte6);

 

Looks awfull I know, but it is what the C compiler most likely does in fact. As mentioned before there is a slight change that the C compiler actually packs 4 bytes into a single int32 parameter (for Win32 anyways, would be likely different for Win64) . In that case instead of 6 individual paramaters each for every array you only had two, with the first 4 bytes in the first parameter and the last two in the second parameter. I can't vouch for one or the other, and feel a little to lazy to create the code and look at the assembly code to see which one it would be.

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 11 of 20
(1,646 Views)

I am very sorry, I forgot to add another information. The .c file was made from a call library function with the variable declared as array, just like the screenshot here:

call_lib_array.png

The expected .c file from this kind would be like the one mentioned in your post?

0 Kudos
Message 12 of 20
(1,639 Views)

@triple5 wrote:

I am very sorry, I forgot to add another information. The .c file was made from a call library function with the variable declared as array, just like the screenshot here:

 

The expected .c file from this kind would be like the one mentioned in your post?


No!

 

Each array parameter needs to be changed into 6 individual byte parameters passed by value (or possibly into two int32 parameters passed by value).

 

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 13 of 20
(1,635 Views)

If that's the case then the DLL really has to change, right? If I have to declare each and every array element then I wouldn't be passing the correct parameters to DLL function, as it has only around 8+ elements in it.

 

Are there any way that I could see what's going on between labview and the DLL?

 

Sorry for forgetting, thanks for all your help so far. It has given some clues to this problem

0 Kudos
Message 14 of 20
(1,621 Views)

@triple5 wrote:

If that's the case then the DLL really has to change, right? If I have to declare each and every array element then I wouldn't be passing the correct parameters to DLL function, as it has only around 8+ elements in it. 

 

Are there any way that I could see what's going on between labview and the DLL?

 

Sorry for forgetting, thanks for all your help so far. It has given some clues to this problem



Well I counted 9 skalar parameters and  5 fixed size arrays. So it is more like 14 parameters. But how the C syntax appears to your untrained C programmer eye does not have much to do with how the parameters are passed over the stack. C is an abstraction layer, albeit pretty close to the hardware level, but still trying to abstract away many of the nitty gritty details about machine code programming.

 

If you declare a C function parameter func(...,  BYTE param[6]) it may look like a simple array parameter but it is in fact a memory block of 6 bytes which doesn't fit into the int32 used as stack variable space on 32 Bit Windows systems. So the compiler has to do something about it. Passing it as an array pointer may be a solution but that would pose other problems elsewhere, including that a fixed sized array is everywhere else treated as memory block and not a pointer. So it would at least violate the assumption of symmetry, which is not a physical law in programming but still a pretty dominant principle. Also it would cause two syntactically completely different statements "BYTE (*param)[6]" and "BYTE param[6]" to evaluate to the same code in this special case but not in others.

 

The next best thing to do is to stuff those bytes into the stack as that comes closest to the actual meaning of the syntax.

 

As to how to see what is really needed, I'm afraid there are only two venues. Find a C textbook that describes this special case in every detail (I think it's unlikely you find that), or create a test program in C, disassemble it and analyze the disassembly of the calling code. And although I don't think it applies here, beware that C has in fact many things that fall under the so called undefined behaviour, meaning a C compiler is actually free to choose in such situations between whatever suits the compiler developer best choosing between

- suiting his sense of beauty and symmetric design

- the most easy way out

- or even simply creating in fact defective code.

 

The best way out would be to change the DLL parameter declarations to meet the syntax BYTE (*param)[6]. In this way you can treat them in the Call Library Node as Array Data Pointer of size 6. But it requires changes to the DLL, and also the internals of the function, to reference the bytes from the array pointer instead of the array block. Also any C software that has already been developed needs to be adapted as well, unless you create a new DLL version with a different name just for LabVIEW use.

 

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 15 of 20
(1,613 Views)

@rolfk wrote:

A fixed size array is not the same as a pointer to a variable sized array. If you want a pointer to a fixed size array, you have to declare that as such. The fixed sized array variable is NOT a pointer in itself, but directly the memory area that is occupied by the array.


Rolf - I'm constantly impressed by your knowledge of the details of C, but are you sure about this?  I can't find any source that says that an array as a function parameter will be passed differently if it's declared as array[] versus array[x] (and it would be odd if those were different, in my opinion).  To confirm this I wrote a tiny C program in which a function modifies an element of a fixed-size array passed as a parameter, and then prints that element after returning to main.  The printf statement shows that the element is modified, so the array must be passed by reference.

 

This doesn't help the poster with the problem of not getting the error code he expects, but I don't think it will help to pass each array element individually.

0 Kudos
Message 16 of 20
(1,602 Views)

@triple5 wrote:

If that's the case then the DLL really has to change, right? If I have to declare each and every array element then I wouldn't be passing the correct parameters to DLL function, as it has only around 8+ elements in it.


Simplifying what Rolf said: no, you don't need to change the DLL.  There are some situations in which the function prototype according to the Call Library Function Node will not match the function prototype according to the C header file, and Rolf thinks this may be one of them.  I'm not convinced about this, as I explained above, but I don't have any other explanation for you either, other than that perhaps your DLL is fine and it just doesn't return an error code for this function even if the data is invalid.

0 Kudos
Message 17 of 20
(1,599 Views)

@nathand wrote:

@rolfk wrote:

A fixed size array is not the same as a pointer to a variable sized array. If you want a pointer to a fixed size array, you have to declare that as such. The fixed sized array variable is NOT a pointer in itself, but directly the memory area that is occupied by the array.


Rolf - I'm constantly impressed by your knowledge of the details of C, but are you sure about this?  I can't find any source that says that an array as a function parameter will be passed differently if it's declared as array[] versus array[x] (and it would be odd if those were different, in my opinion).  To confirm this I wrote a tiny C program in which a function modifies an element of a fixed-size array passed as a parameter, and then prints that element after returning to main.  The printf statement shows that the element is modified, so the array must be passed by reference.

 

This doesn't help the poster with the problem of not getting the error code he expects, but I don't think it will help to pass each array element individually.


Ok, you made me want to know myself for sure now, and you are right. At least Visual C 2005 does compile a

 

char param[6]

 

function parameter as a pointer. I created a small test DLL and checked the generated assembly code.

 

In fact all kinds of syntaxes like

 

char (*param)[6]

char param[6]

char param[]

char *param

 

are treated as data pointers when declared in a function parameter list. Of course they still have different semantics in terms of out of bounds compile time checks, and also are treated rather differently in other areas such as inside cluster declarations, but at least as function parameters they cause the same code to be created.

 

So C compilers seem to prefer to use the more performant solution rather than trying to maintain symmetry.

 

I do have reasons to believe that some compilers may in fact choke on char param[6] as function parameter declaration, but should really work fine with char (*param)[6].

 

So in hindsight the original VI should have worked and if it doesn't return an error code as expected, either the expectation is wrong or there is something else going on.

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 18 of 20
(1,595 Views)

While I'm also impressed with the explainations the OP has access to the header fileSmiley Surprised

So

Untitled.png

Lets let LabVIEW figure it out for usSmiley Very Happy


"Should be" isn't "Is" -Jay
0 Kudos
Message 19 of 20
(1,591 Views)

@JÞB wrote:

While I'm also impressed with the explainations the OP has access to the header fileSmiley Surprised

So

 


 

Well yes, and it has gotten pretty decent but I have to admit I never use it! For the types of DLLs I interface with usually, it still keeps choking on various things. The created front panels are quite a mess, error clusters are not generated since they don't exist in the function prototypes, and some C syntax elements are simply unsupportable in an automated way in LabVIEW.

 

Besides it is a C syntax parser written in LabVIEW by someone who probably knows quite a bit about C syntax, but it is not a C compiler. So I wouldn't trust it to do always the right thing, especially in such corner situations. I don't even trust a C compiler to do the right thing until it has been seriously tested. Some C compilers have been creating simply wrong code already. Some GCC versions have been notorious for that, but every compiler under the sun can create wrong code sometimes.

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
Message 20 of 20
(1,587 Views)