09-17-2012 10:05 AM - edited 09-17-2012 10:17 AM
Hello all,
I am using a Call library function to call a function in a DLL (The DLL is not written by me, I am suppose to create a VI that calls these functions ). The variable requires an array of 6 elements, and is declared in the following manner:
_INT_ MyInitFunction(...., BYTE_ channel[6],...)
So what I did was to declare the variable as an array of 6 elements. I defined the data type as an unsigned 8 bit integer, with a minimum size of 6.
It does work, well, sort of. The function is supposed to return an error code if not executed properly. The problem I have is that the function does not return an error code despite me delibarately passing false values to the VI. I believe that there's something to do with the way the array is passed from labview to the DLL. I've made other VIs using the Call Library function that uses the same DLL and I managed to have the error codes. The only difference being that these other functions do not use arrays.
Could someone enlighten me on how these arrays are supposed to be declared with the above header? I don't think I did anything wrong but I might miss something. I attached some images to help understand the problem. Call_lib_window shows how the variable is declared in labview and func_header image shows the function header
09-17-2012 10:26 AM
Looks to me like you're passing the arrays properly. Are you certain the values are invalid? Have you checked the "Error Out" indicator from the Call Library Function Node to see if there's any error when LabVIEW calls the library? If so, you will not get any error code from the library function since the library function will not be called properly.
An alternate way to pass a fixed-size array is to pass a cluster containing the same number of elements (in this case, a cluster containing six U8 values) but I don't believe that's necessary here.
09-18-2012 02:13 AM
I used the "Error out" indicator, but not directly. I've attached another screenshot to show how I do it. The array index is used to display the error messages as defined in the array constant. The "Error Out" indicator is supposed to display errors (I delibarately used the wrong settings to get the error out) but nothing comes out. That's why I suspected that there's probably something the arrays may not be passed around correctly from labview to the DLL.
09-18-2012 12:17 PM
The Call Library Function Node itself has an error cluster out, which is not wired in your image. Can you put an indicator on that and see if the Call Library Function is generating an error itself?
09-19-2012 12:57 AM - edited 09-19-2012 01:15 AM
Hmmm, C syntax can be difficult. Are you absolutely sure
BYTE param[6]
is treated the same as:
BYTE (*param)[6]
The first is similar to a cluster containing 6 bytes passed by value, the second is the same cluster passed by reference.
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.
For your case you should try to change either the DLL parameter syntax or pass the 6 bytes as individual parameters each.
09-19-2012 01:58 AM
@nathand: I tried connecting the error cluster as you suggested, but there no error codes are called. Despite not having the correct settings.
@rolfk: I can't change the DLL parameter (or rather the DLL is final, no changes are to be made unless necessary. I didn't developed the DLL btw). SO I guess I'll have to try and pass the 6 bytes as individual parameters. How could I do that?
09-19-2012 02:13 AM - edited 09-19-2012 02:22 AM
Instead of an array, you have to create 6 byte parameters. So your Call Library Node gets VERY large!! There is a chance that the function expects the parameters packed into 32 bit integers on the stack. Not really sure about that, but I somehow doubt that.
Passing fixed size arrays by value instead of pointer is a sure way to create very stack intense functions. If you would call that function recursively you can run out of stack space easily even on modern computers.
Personally I would consider such parameters a good reason to declare a necessary change to the DLL!
And you probably use stdcall calling convention for that function. With C calling convention, the misadjusted stack pointer resulting from the wrongly configured parameter list, surely would have crashed your code very quickly (or at least generated a 1097 error if you were using the highest Call Library Node debug setting).
09-19-2012 02:42 AM
Oouuuccchhhhhh.......God help me if I have to change the DLL, it's written in such an ancient language that mere mortals such as I tremble before its very sight.
Well jokes aside, previously I made it like this:
So with 6 individual parameters I have to do something like this, but 6 times I suppose?:
As you've mentioned in the last line, I used stdcall and not C calling convention. I did change it to C once to see any changes but nothing happened.
09-19-2012 03:06 AM - edited 09-19-2012 03:13 AM
Yes you have to do that 6 times for every array in the parameter list. All in all 30 byte parameters in addition to the already 10 or so.
If the DLL was written in Fortran or similar I would agree that it's an ancient language. Standard C is still one of the most used languages though.
Changing to C calling convention should have generated at least a 1097 error in the Call Library Node error cluster. But sometimes you get unlucky and even totally wrong code doesn't crash right away.
09-19-2012 04:14 AM - edited 09-19-2012 04:17 AM
well yeah C is still used until today. What I meant is that it's as old as Fortran or Delphi :D( these two are a few of those barely-alive-but-not-quite-dead-languages :D)
I printed the C header made by Call library function. This is what I get:
Compared to the function that I must call in the DLL:
What do you think?