LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

LabView strings in LabWindows ?

Solved!
Go to solution

Hello all, it's been a while...

 

I'm currently analyzing some code that uses LabView-style strings (which I suspect are the same as Pascal strings):

typedef struct {
	int	cnt;		/* number of bytes that follow */
	char	*str;		/* cnt bytes */
} LStr, *LStrPtr, * *LStrHandle;

Are there CVI libraries that allow you to manipulate those directly, or do I have to roll my own (OK, it's not that complicated) ?

0 Kudos
Message 1 of 5
(3,175 Views)

Correction, the code for LV strings is the following:

 

typedef struct {
    int    cnt;        /* number of bytes that follow */
    char    str[1];        /* cnt bytes */
} LStr, *LStrPtr, * *LStrHandle;

LStrPtr Str;
length = strlen(controller);
Str = ( LStrPtr )malloc(sizeof(int) + length * sizeof(char));
sprintf( (char *)Str->str ,"%s" ,controller);
Str->cnt= length;

And execution fails on the next to last line with: "Attempt to write beyond end of string", which makes sense to me since the struct officially has a size of 5, even if we place it into a larger malloc. CLang, used by CVI, does not seem to support 0-length arrays. Is this the correct way to handle LV strings ?

 

Replacing the str[1] with a pointer loses the fact the it's contiguous in memory with cnt, and doesn't seem to work anymore.

0 Kudos
Message 2 of 5
(3,154 Views)
Solution
Accepted by topic author gdargaud

Hi gdargaud,

 

I was able to find a forum post that has a recommendation on how to call these strings from LabVIEW and allocate memory appropriately. I have attached it below.

 

Problem using a LabView DLL in LabWindows: http://forums.ni.com/t5/LabWindows-CVI/Problem-using-a-LabView-DLL-in-LabWindows/td-p/105378

 

This seems similar to what you are doing, but with some additional memory allocation.

 

Thanks,

 

ShaneK

Applications Engineering

0 Kudos
Message 3 of 5
(3,112 Views)

Doing your own malloc() and free() calls will work like LabVIEW does but it will not work with strings coming from LabVIEW or going to it. LabVIEW allocates its strings in a specific way using its own memory manager functions. And the LabVIEW way is that any memory that is passed to a function or out of a function is then owned by that function and needs to be managed accordingly.

 

So if you want to do your own LabVIEW style strings to use in your own application without interfacing to LabVIEW you could do what you want to do. But why would you want to do that then?

But if you want to create, modify and delete strings that come or go to a LabVIEW DLL for instance, you absolutely have to link your code with labviewv.lib in the cintools directory and use the according LabVIEW memory manager functions like NumericArrayResize() or DSNewHandle(), DSSetHandleSize(), DSDisposeHandle().

 


Replacing the str[1] with a pointer loses the fact the it's contiguous in memory with cnt, and doesn't seem to work anymore.


Of course. That is how C works. char *str is a pointer to a string or byte array and the C compiler allocates exactly 4 (or 8 bytes for 64 bit) for that pointer.

char str[1] is a fixed size array and the C compiler allocates exactly 1 byte for the string.

 

And your code has other errors. You allocate a memory block for sizeof(in32) + strlen() characters but use a Standard C string function to format the string into this buffer. Standard C strings are zero terminated and sprintf() will append this zero byte at the end overwriting memory that does not belong to the allocated buffer!

Rolf Kalbermatter
My Blog
0 Kudos
Message 4 of 5
(3,088 Views)

Yeah, you are both correct. In the code samples I had, they were mixing strlen and sizeof, sometimes on static strings, sometimes on dynamic ones, so it was very confusing to follow and my copy-pasted sample was indeed buggy and the real code had several off-by-one errors detected by CVI but that seemed to run 'fine' on gcc. I'm cleaning it up now.

0 Kudos
Message 5 of 5
(3,056 Views)