01-20-2009 11:14 AM
Hi all,
I'm using LV 7.1 and am trying to access a function in a DLL. The function takes a pointer to a data structure that is large and complex. I have calculated that the structure is just under 15kbytes.
I have built the structure as a cluster and then attempted to pass the cluster into the call library function node with this parameter set as adapt to type. I get memory error messages and when analysing the size of the cluster I am producing it appears to be much smaller than required.
I have also tried creating an array and passing that but I think that won't work as it needs to be a fixed size of array which can only be acheived, according to what I've read, by changing it to a cluster and this is limited to a size of 256.
Does anybody have a suggestion of how to overcome this?
If any more detail is required then I'm happy to supply.
Dave.
01-20-2009 01:14 PM
01-20-2009 01:59 PM
Hi.
I read the size of the cluster I am trying to build by flattening it to a string and reading the string length, this is a method I found on the forum. I calculated the size of the cluster that is defined by adding up all the sizes of the variables defined in it.
The structure I am trying to build is attached. As I said, it is a complex structure.
I haven't considered memory alignment. I assume you mean that if for instance I have a byte followed by a word and then this takes up 4 bytes rather than 3. In this case, if the structure is correct according to what I require then my method above would read back a size that is either equal to or greater than my calculated size as my calculation doesn't take account of alignment. When I read back the size however, it is smaller than required.
The 256 limit is when you are converting from an array to cluster, the limit on that is 256 elements. This is not the overall limitation I am concerned about which appears to be somewhere around 10kbytes.
Dave.
01-20-2009 02:32 PM
There is a difference between the size of a cluster in terms of the number of bytes it takes up and the size of a cluster in terms of the number of elements. The latter has a hard limitation. The former does not. When you flatten a cluster to a string you get the former. For example, a cluster that consists of a DBL and a Boolean is 9 bytes long (8 + 1), but has only 2 elements.
In terms of your issue, it appears you have a situation similar to the one that was discussed in the thread to which I pointed to. You have unions as struct members. The union part will be 32 bytes long since the longer union member is the second one (unsigned char raw[32]). If you were to do this in LabVIEW you should make the cluster element an array of U8 numbers to guarantee you meet the union's expected size. Your most likely problem is that you are not creating arrays with no elements. For example, let's say you've created a cluster to represent the XLchannelConfig structure. When you bundle this into the cluster to represent the XL_DRIVER_CONFIG structure are you using Build Array or Initialize Array with the dimension size input set to 64? The former is incorrect, the latter is correct, since you want to make sure to allocate the memory for 64 of these little critters.
Perhaps if you post your LabVIEW code we could be of more help.
01-21-2009 03:34 AM - edited 01-21-2009 03:35 AM
smercurio_fc wrote:There is a difference between the size of a cluster in terms of the number of bytes it takes up and the size of a cluster in terms of the number of elements. The latter has a hard limitation. The former does not. When you flatten a cluster to a string you get the former. For example, a cluster that consists of a DBL and a Boolean is 9 bytes long (8 + 1), but has only 2 elements.
In terms of your issue, it appears you have a situation similar to the one that was discussed in the thread to which I pointed to. You have unions as struct members. The union part will be 32 bytes long since the longer union member is the second one (unsigned char raw[32]). If you were to do this in LabVIEW you should make the cluster element an array of U8 numbers to guarantee you meet the union's expected size.
No please do not use arrays or strings in a cluster and pass them to a Call Library Node whose function expects fixed size arrays and strings. LabVIEW array and strings are always variable sized while C array and strings can be fixed or variable sized. For variable sized arrays C uses simply a pointer (4 bytes) inside the structure and the string is allocated somewhere else in memory. strict sized arrays and strings are directly embedded into a structure and consume as many bytes as they would need. LabVIEW strings and arrays are however handles (pointers to pointers) and C code can only deal with them if it was explicitedly written with LabVIEW datatypes in mind.
The only way in LabVIEW to create fixed size arrays and strings in a cluster is to embed another cluster with the correct amount of uInt8 integers in there. Also you need to be aware of alignement issues. LabVIEW always packs the elements on non PPC architectures as tight as possible while most Windows DLLs for instance are compiled with an alignment of 8 Bytes. Alignment is the term used to define on what address boundary an element inside a structure is getting aligned. The actual alignment of a structure element is always the smaller of the two values "element size in bytes" and the selected "alignment".
Rolf Kalbermatter
01-21-2009 06:05 AM
It's looking more and more like I need to write a C wrapper DLL that returns the data I need in a much more LabView friendly manner. I was trying to avoid this as it's an extra level of effort.
Dave.
01-21-2009 10:16 AM
01-21-2009 10:43 AM
For some completeness, this is the cluster I have tried to build according to the C above. I have ensured that all arrays are converted to clusters so that the size is fixed as required.
Note the array to cluster highlighted, despite the specified maximum being 256 for the cluster size, I can't set a size larger than 45 at this point.
01-23-2009 05:20 AM
Hi Dave,
You have already received some good advice from the community but I wanted to offer my opinion.
I am unsure as to why the cluster size will not exceed 45, my only suggestion is to try using a type cast node as this is the suggested method for converting from array to cluster with greater than 256 elements.
If this still does not work then in this case I would recommend that you do use a wrapper DLL, it is more work but due to the complexity of the cluster you are currently trying to create I would suggest this is a far better option.
Have a look at this KB article about wrapper DLL's.
Hope this helps,
John P
05-20-2009 06:11 PM - edited 05-20-2009 06:11 PM
John, I am having a hard time converting an array of greater than 256 elements to a cluster. I attempted to use the type cast node you suggested and didn't have any luck. Please see the attached files... I’m sure I’m doing something wrong. The .txt file has a list of 320 elements. I want to run the VI so that in the end I have a cluster containing equal number of integer indicators/elements inside. But more importantly, I don't want to have to build a cluster of 320 elements. I'd like to just change the number of elements in the .txt file and have the cluster automatically be populated with the correct number of elements and their values. No more, no less. One of the good things about the convert array to cluster was that you could tell the converter how many elements to expect and it would automatically populate the cluster with that number of elements (up to 256 elements only). Can the type cast node do the same thing? Do you have any advice? I posted this question with more detail to my application at the link below... no luck so far.
John.P wrote:Hi Dave,
You have already received some good advice from the community but I wanted to offer my opinion.
I am unsure as to why the cluster size will not exceed 45, my only suggestion is to try using a type cast node as this is the suggested method for converting from array to cluster with greater than 256 elements.
If this still does not work then in this case I would recommend that you do use a wrapper DLL, it is more work but due to the complexity of the cluster you are currently trying to create I would suggest this is a far better option.
Have a look at this KB article about wrapper DLL's.
Hope this helps,
John P
http://forums.ni.com/ni/board/message?board.id=170&thread.id=409766&view=by_date_ascending&page=1