08-13-2026 05:29 AM
I saw a VI at work that calls this C function from a DLL:
int ELECTRONIC_STAMP_Read(FATHANDLE fatHandle, Read_ELECTRONIC_STAMP* data);
The definition of the struct is:
typedef struct
{
char errorCode;
char fileBuffer[3000];
} Read_ELECTRONIC_STAMP;
I don't know if the buffer is intended to be a raw byte buffer or a null-terminated string.
And the VI looks like this:
In the CLFN, MooNElectronicStamp parameter is set as Adapt to Type, Handles by Value.
But, I don't really know why is it working.
Aren't you not supposed to first convert the array to a cluster?
And why is it an array of string since LV strings don't have the same size in memory than a byte? Also I don't know why there are 1500 elements instead of 3000.
Solved! Go to Solution.
08-13-2026 07:30 AM
@caenem wrote: why is it working.
I think it is working only "occasionally" because what you're sending (an array of LabVIEW strings) is actually an array of handles, where each handle contains a pointer to the string data and its length, not matched to the structure.
You may simply not be accessing those data structures correctly, which is why you haven't seen a crash yet.
What I would recommend is creating your own simple DLL, passing the same type of data to it, then reading an element from the array at a given index and checking what you get back and do some experiments:
char ELECTRONIC_STAMP_Read(int index, Read_ELECTRONIC_STAMP* data)
{
if ((index >= 0) && (index < 3000)) {
return data->fileBuffer[index];
}
return data->errorCode;
}
And then everything will be much clearer.
08-13-2026 07:44 AM - edited 08-13-2026 07:52 AM
@Andrey_Dmitriev wrote:
@caenem wrote: why is it working.I think it is working only "occasionally" because what you're sending (an array of LabVIEW strings) is actually an array of handles, where each handle contains a pointer to the string data and its length, not matched to the structure.
Doesn't the String array allocate 1500 pointers á 4 bytes in a block? Technically ~6kb when the cluster needs 3k, or am i misunderstanding stuff (again)? (trying to figure out how/if it works).
Isn't this how you're supposed to do it?
Yamaeda_0-1786625560305.png
08-13-2026 10:36 AM
@Yamaeda wrote:Doesn't the String array allocate 1500 pointers á 4 bytes in a block? Technically ~6kb when the cluster needs 3k, or am i misunderstanding stuff (again)? (trying to figure out how/if it works).
Isn't this how you're supposed to do it?
Yamaeda_0-1786625560305.png
If you're unsure how LabVIEW data should be passed to a DLL, here's a very useful trick: simply create the C source/header file from the Call Library Function Node configuration and look at the generated data types (you don't need to have DLL):
image-20260813171309755.png
For example, in the first message
image-20260813171428885.png
the generated code looks like this (I'll omit the `lv_prolog.h` / `lv_epilog.h` parts):
/* Typedefs */
typedef struct {
int32_t dimSize;
LStrHandle elt[1];
} TD2;
typedef TD2 **TD2Hdl;
typedef struct {
uint8_t errorCode;
TD2Hdl initializedArray;
} TD1;
void funcName(TD1 *arg1);
In your case,
image-20260813171649427.png
the generated structure would look something like this:
typedef struct {
LStrHandle _00;
LStrHandle _11;
LStrHandle _22;
...
} TD2;
typedef struct {
uint8_t errorCode;
TD2 elt2;
} TD1;
And so on.
For the original C structure actually needed is trivial array of 3000+1 of u8 passed as a pointer:
image-20260813172220153.png
In that case, the structure layout would match, because there is no padding between those members.
The important point is that when an array is placed inside a LabVIEW cluster, LabVIEW represents the array as a handle. As a result, the memory layout is different, and not every C structure can be mapped directly to an "equivalent" LabVIEW cluster. In some cases, an array must be passed separately, and in others, padding/alignment gaps between elements must be taken into account (although that is not the case in this particular example).
refer to https://www.ni.com/docs/en-US/bundle/labview/page/how-labview-stores-data-in-memory.html
08-15-2026 06:01 PM - edited 08-15-2026 06:02 PM
@Yamaeda wrote:
Doesn't the String array allocate 1500 pointers á 4 bytes in a block? Technically ~6kb when the cluster needs 3k, or am i misunderstanding stuff (again)? (trying to figure out how/if it works).
Isn't this how you're supposed to do it?
Yamaeda_0-1786625560305.png
Yes it does, but that does not result in what you think it does. This array of strings is a handle, a pointer to a pointer, so it only passes a 4 byte (or 8 byte) integer after the initial 1 byte for the error code, a far cry from the 3000 bytes the function expects.
Worse, if the function tries to write anything in that buffer, which it may only do if there was an error to report it will not only destroy this handle but also loose all the string handles in the array.
And when the function returns and LabVIEW tries to deallocated that array of handles it will totally trip over its feet and almost certainly give you a General Protection fault or similar.
08-18-2026 07:47 AM
@rolfk wrote:
@Yamaeda wrote:
Doesn't the String array allocate 1500 pointers á 4 bytes in a block? Technically ~6kb when the cluster needs 3k, or am i misunderstanding stuff (again)? (trying to figure out how/if it works).
Isn't this how you're supposed to do it?
Yamaeda_0-1786625560305.png
Yes it does, but that does not result in what you think it does. This array of strings is a handle, a pointer to a pointer, so it only passes a 4 byte (or 8 byte) integer after the initial 1 byte for the error code, a far cry from the 3000 bytes the function expects.
Worse, if the function tries to write anything in that buffer, which it may only do if there was an error to report it will not only destroy this handle but also loose all the string handles in the array.
And when the function returns and LabVIEW tries to deallocated that array of handles it will totally trip over its feet and almost certainly give you a General Protection fault or similar.
Hmm, it doesn't send the Array-pointer? I imagined it managed to work due to allocating some memory in the wrong way.
08-18-2026 09:06 AM
@Yamaeda wrote:
@rolfk wrote:
@Yamaeda wrote:
Doesn't the String array allocate 1500 pointers á 4 bytes in a block? Technically ~6kb when the cluster needs 3k, or am i misunderstanding stuff (again)? (trying to figure out how/if it works).
Isn't this how you're supposed to do it?
Yamaeda_0-1786625560305.png
Yes it does, but that does not result in what you think it does. This array of strings is a handle, a pointer to a pointer, so it only passes a 4 byte (or 8 byte) integer after the initial 1 byte for the error code, a far cry from the 3000 bytes the function expects.
Worse, if the function tries to write anything in that buffer, which it may only do if there was an error to report it will not only destroy this handle but also loose all the string handles in the array.
And when the function returns and LabVIEW tries to deallocated that array of handles it will totally trip over its feet and almost certainly give you a General Protection fault or similar.
Hmm, it doesn't send the Array-pointer? I imagined it managed to work due to allocating some memory in the wrong way.
No, a LabVIEW handle is an pointer to the array pointer, and there is a 32 bit value at the beginnning of the array pointer indicating the number of elements in the array pointer.
There is no way to have the Call Library Node automatically convert LabVIEW arrays inside clusters to C array pointers. That's only possible for LabVIEW arrays directly passed to the Call Library Node.
It pretty much only could work if the function for some reason does not try to touch the embedded 3000 byte string array. Any attempt to write in there by the DLL function will destroy the reference to the LabVIEW array and that will blow up LabVIEW as soon as the Call Library function returns to LabVIEW and LabVIEW dutifully tries to manage the array handle (either reading from it and/or deallocating it).