05-30-2014 10:48 AM
Hi,
I'm trying to interface some functions from dll that is used to control a camera. There are functions that pass const handles to array.
For example, the following function takes an identifier to the camera being used (PicamHandle camera), and put the list of the camera parameters at the adress referenced by the array handle (**parameter array), and put the number of parameters in the list at the adress referenced by the int pointer (*param count):
PICAM_API Picam_GetParameters(PicamHandle camera, const PicamParameter** parameter_array, piint* parameter_count);
where parameter_array is an handle to an array of type enum. and the return value is a error code of type u32
I defined a call library function node of the function with the following parameters:
So if I understand this shoul pass the handle of the initialized array wired at the input to the function, and put the parameters data in the output array:
The problem is that running this crashes labview!
Somebody has an idea of what's wrong?
05-30-2014 01:13 PM - edited 05-30-2014 01:30 PM
No you can't do that! A LabVIEW array handle is not just a double referenced pointer but a very specific LabVIEW datatype that no other external C API is likely to understand or be able to deal with, UNLESS it was specifically written to use that datatype by using LabVIEW manager functions (and in that case that DLL can not be loaded by any other process than LabVIEW or a LabVIEW build executable).
First, unless you use LabVIEW < 2009 you should define the PicamHandle as a pointer sized (unsigned) integer value.
Second there is no easy way to do what you intend to. Most likely (this can't be deducted for certain from the header file alone) this function will return a pointer to an internally allocated array of enum values. Therefore you need to define this parameter as a pointer sized integer that is passed by reference.
Then you need to use the MoveBlock() function call in a second Call Library Node to copy the content from this pointer into a properly allocated LabVIEW array.
First take the number returned in the 3rd Parameter and allocate an array of that many uInt32 elements with the Initialize Array function.
You would configure the MoveBlock() CLN as follows:
Library Name: LabVIEW (upper/lowercase is important here)
Calling Convention: cdecl
return value: void
1. param: pointer sized integer passed by value, connect the parameter array pointer from the 2nd parameter of your GetParameters function to the left side of this parameter.
2. param: array of uIn32, pass array data pointer, connect the allocated integer array to the left side of this parameter and on the right side you get the filled in values in the array out.
3. param: int32, connect the value returned in the 3rd parameter of your GetParameters() function multiplied by 4 to the left side of this parameter
I found the documentation to the API on the web, and it seems to much what I had assumed, but there is one other important remark about the returned array:
You need to dealloate this array using the Picam_DestroyParameters() function! So after the MoveBlock() function has executed do not forget to also call the Picam_DestroyParameters() or you are creating a memory leak there.
05-31-2014 05:21 PM
Two edits in the text:
No you can't do that! A LabVIEW array handle is not just a double referenced pointer but a very specific LabVIEW datatype that no other external C API is likely to understand or be able to deal with, UNLESS it was specifically written to use that datatype by using LabVIEW manager functions (and in that case that DLL can not be loaded by any other process than LabVIEW or a LabVIEW build executable).
First, unless you use LabVIEW < 2009 you should define the PicamHandle as a pointer sized (unsigned) integer value.
Second there is no easy way to do what you intend to. Most likely (this can't be deducted for certain from the header file alone) this function will return a pointer to an internally allocated array of enum values. Therefore you need to define this parameter as a pointer sized integer that is passed by reference.
Then you need to use the MoveBlock() function call in a second Call Library Node to copy the content from this pointer into a properly allocated LabVIEW array.
First take the number returned in the 3rd Parameter and allocate an array of that many uInt32 elements with the Initialize Array function.
You would configure the MoveBlock() CLN as follows:
Library Name: LabVIEW (upper/lowercase is important here)
Function Name: MoveBlock
Calling Convention: cdecl
return value: void
1. param: pointer sized integer passed by value, connect the parameter array pointer from the 2nd parameter of your GetParameters function to the left side of this parameter.
2. param: array of uIn32, pass array data pointer, connect the allocated integer array to the left side of this parameter and on the right side you get the filled in values in the array out.
3. param: int32, connect the value returned in the 3rd parameter of your GetParameters() function multiplied by 4 to the left side of this parameter
I found the documentation to the API on the web, and it seems to match what I had assumed, but there is one other important remark about the returned array:
You need to dealloate this array using the Picam_DestroyParameters() function! So after the MoveBlock() function has executed do not forget to also call the Picam_DestroyParameters() or you are creating a memory leak there.