jsousa Posted June 28, 2010 Report Share Posted June 28, 2010 Hello, I am attempting to send an array of clusters from LV to a C/C++ DLL written in MS Visual C++ 2010. The clusters have strings (LV strings converted to U8 Char Arrays) and an integer (representing the size of the U8 Char Arrays). The process I went through was to create the array of clusters and then send the array as an input to the call library function node along with an I32 representing the number of elements in the array (2 for now to keep it simple). I selected Adapt To Type as the data type and am not sure which data format to use. I have created a skeleton c file for both Array Data Pointer and Handles By Value (array data pointer is apparently a newer feature). Looking at the skeleton .c file created with Array Data Pointer as the format...it is fairly blank and has void as the data types. With Handles By Value, the C code looks similar to the C file created by sending the array into a CIN and creating a skeleton c file that way. I am having difficulty understanding how to manipulate the LV data in the DLL file with the typedefs created by labview (I just copied over the skeleton c file typedefs to the dll) and was wondering if anyone could explain to me the best way to manipulate the data and if I should use Handle By Value or Array Data Pointer for the data format (I am fairly new to C/C++). Here are the typedefs created by labview with the Handles by Value or with the array going into a CIN: /* Typedefs for array of clusters with strings */ typedef struct { int32 dimSize; uInt8 elt[1]; } TD3; typedef TD3 **TD3Hdl; typedef struct { TD3Hdl unsignedByteArray; int32 elt2; } TD2; typedef struct { int32 dimSize; TD2 elt[1]; } TD1; typedef TD1 **TD1Hdl; I imagine dimSize for TD1 is the size of the array (so maybe I don't have to pass that into the fct as a separate argument?) and that dimSize for TD3 is the size of the U8 char array. Does TD3Hdl represent a handle to the individual unsignedByteArrays? Any help would be greatly appreciated. Thanks very much Quote Link to comment
cschneider Posted July 5, 2010 Report Share Posted July 5, 2010 Hi, the way you are using is totally right...create the cluster, wire it to a call library node and then create the c file. I only worked with "Handle by Value" because, as you already said, the other is totally blank. To manipulate the data, I have to say that it's not allowed by labview to alter the size of you data...that means adding of array elements is not possible, you can only manipulate existing elements. For other things (expanding of your array), you have to use CIN-nodes (but I never worked with them so far) If you pass an array, the size of the array is added in the struct, as you said. so dimSize is the size of your array, elt[1] the first array element. In Labview, data is represented by "Handles", that means "Pointers to Pointers to struct"..what means that you have to dereference it first if you like to access it (with the **). So if you create an object (i hope I am right as I write this code out of my mind... ;-)): TD3Hdl handle; int dimension_size=(*handle)->dimSize; OR int dimension_size=(**handle).dimsize -> means something like "dereference and access of object", whereas . means only access to object. Like this, you can expand your code to more complex structures. If you have, for example, another structure like "TD2Hdl" (which you don't have at the moment), then you can by (*td2handle)->unsignedByteArray access your unsignedByte-Array variable fo type TD3Hdl and then, by *((*td2handle)->unsignedByteArray)->dimSize access the upper dimSize...and so on, and so on, and so on.. Hope this helps, good luck Christian /* Typedefs for array of clusters with strings */ typedef struct { int32 dimSize; uInt8 elt[1]; } TD3; typedef TD3 **TD3Hdl; typedef struct { TD3Hdl unsignedByteArray; int32 elt2; } TD2; typedef struct { int32 dimSize; TD2 elt[1]; } TD1; typedef TD1 **TD1Hdl; I imagine dimSize for TD1 is the size of the array (so maybe I don't have to pass that into the fct as a separate argument?) and that dimSize for TD3 is the size of the U8 char array. Does TD3Hdl represent a handle to the individual unsignedByteArrays? Any help would be greatly appreciated. Thanks very much Quote Link to comment
jsousa Posted July 6, 2010 Author Report Share Posted July 6, 2010 Hello, Thanks for your reply. I have figured out how to manipulate the data with the "Array Data Pointer" data format. It is actually quite easy. You simply need the type def for the cluster that you are passing in with the array. Then you change the void in the fct prototype created by labview to match whatever typedef you created. You can access individual elements in the array by incrementing the pointer to the array. For instance, passing in an array of simple clusters to the DLL (simple meaning just two unsigned 8 bit ints), you create the typedef in the header file and passing in say "ClusterArrayIn" with the prototype looking like so... void passClusterArray(TD1 *ClusterArrayIn) all you do is replace the void created by LV when you right click the Call Library Function Node with the Typedef defined by the type of cluster you are passing. with type def 1 being the cluster and the type def looking something like this typedef struct { uint8 num1; uint8 num2; } TD1; void passClusterArray(TD1 *ClusterArrayIn) { (ClusterArrayIn+1)->num1 = 10; (ClusterArrayIn+1)->num2 = 11 } There may be an easier way to manipulate the data but this isn't too bad. It just took a while to figure out how to do this because the documentation on it is not great. Also, you must pass in the length of the array as a separate argument. But that is easy because you can pass that by value! Thanks for the assistance Quote Link to comment
Wolfcastle Posted August 17, 2010 Report Share Posted August 17, 2010 Hello there, I just checked out your example passing in an array of clusters. What I tried but did not work is this example: I created an array of clusters of two elements. then I selected "adapt to type", handle through value The resulting c Code for the types is this one typedef struct { double x; double y; } TD2; typedef struct { int32_t dimSize; TD2 Cluster[1]; } TD1; typedef TD1 **TD1Hdl; So, how do I manage to acces e.g. the second cluster element? I tried this: int32_t funcName3(TD1Hdl arg1, int32_t size1, int32_t *value) { TD2 clusterElem = (*arg1)->TD2[1]; return clusterElem.x; } But this code always returns 0. Does anybody know why? Regards Wolfcastle Hello, Thanks for your reply. I have figured out how to manipulate the data with the "Array Data Pointer" data format. It is actually quite easy. You simply need the type def for the cluster that you are passing in with the array. Then you change the void in the fct prototype created by labview to match whatever typedef you created. You can access individual elements in the array by incrementing the pointer to the array. For instance, passing in an array of simple clusters to the DLL (simple meaning just two unsigned 8 bit ints), you create the typedef in the header file and passing in say "ClusterArrayIn" with the prototype looking like so... void passClusterArray(TD1 *ClusterArrayIn) all you do is replace the void created by LV when you right click the Call Library Function Node with the Typedef defined by the type of cluster you are passing. with type def 1 being the cluster and the type def looking something like this typedef struct { uint8 num1; uint8 num2; } TD1; void passClusterArray(TD1 *ClusterArrayIn) { (ClusterArrayIn+1)->num1 = 10; (ClusterArrayIn+1)->num2 = 11 } There may be an easier way to manipulate the data but this isn't too bad. It just took a while to figure out how to do this because the documentation on it is not great. Also, you must pass in the length of the array as a separate argument. But that is easy because you can pass that by value! Thanks for the assistance Quote Link to comment
cschneider Posted August 17, 2010 Report Share Posted August 17, 2010 Yeah, you did it all right...it's just a simple C++ Coding error...your variable name is Cluster, the type is TD2... So try changing the line TD2 clusterElem = (*arg1)->TD2[1]; to TD2 clusterElem= (*arg1)->Cluster[1] and see if this works... good luck Chrisitan Quote Link to comment
Wolfcastle Posted August 19, 2010 Report Share Posted August 19, 2010 In between I corrected this "little mistake" but it still did not work. I searched the forum and found this post: http://lavag.org/topic/10373-sending-an-array-of-clusters-to-a-c-dll/ So I used the pragma pack directive and it works! Thanks for your help, Wolfcastle Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.