04-14-2010 09:48 AM
I have a DLL which has a function as follows:
int GetMessageNameNumber (char* messageName [], const int MessageNumber);
The function is used thus:
char *MessageName = NULL; int MessageNumber = 0; ... error = HL1553API_GetMessageNumberName (&MessageName, MessageNumber);
MessageName will then contain the message name as a string.
I having the devils own job trying to wrap this into a Labview module. I have a Call Library function node for the above function, but I am not sure what to set the "MessageName" parameter too! I have tried Array of signed 8-bit integers, Adapt to Type, Array Data Pointer and then passed in a String array. Whatever I do results in LabView crashing. I know HL1553API_GetMessageNumberName works, because if I call it directly in TestStand it works fine. I need it LabView though!
Any ideas?
Solved! Go to Solution.
04-14-2010 10:05 AM
04-14-2010 10:30 AM
Looking how the function is used, it is actually returning a pointer to a string. The code should probably be:
int HL1553API_GetMessageNumberName (char ** MessageName, const int MessageNumber);
I say this because when the function is used in C code it declares a char pointer variable and then uses the address of the char pointer as the parameter.
If I use example you provided it does not crash any more, but the string contains rubbish!
04-14-2010 12:31 PM
04-15-2010 01:56 AM
The strings have a maximum length of 260 characters, but they can be smaller. "this little trick" resulted in random characters being returned. However converting the string to hex, it looks a lot like a memory address to me.
I need to do some more research...
04-15-2010 02:21 AM
In C a pointer to a string or an array of strings are completely ambigues.
char ** something ===== char * something [].
You can not tell the two apart from the syntax but only from the documentation or from an example showing how the function is called. A C compiler treats the two equal in terms of access (but a C++ compiler will make a syntactic distinguishment when syntax checking code, resulting in possible compile warnings when prompted to use a sufficiently high warning level.)
The sample shows that this is not an array of strings that gets allocated by the caller and passed to the function, but a string pointer that gets passed by reference. As such the function will allocate a pointer and return it (a highly non-standard C practice at least for strings). This automatically begs the question when and how will this pointer be deallocated? The documentation for that function should document the memory manager call used to allocate that pointer and also point out the function to call to deallocate it. Ideally the library (DLL) provides a specific exported function for that purpose.
Assuming everything I have talked about so far is clear and available you have to trick LabVIEW a bit. You have to configer a pointer sized integer that gets passed by reference. Now this integer in the diagram IS in fact your string. If you only need to pass this pointer to other Call Library functions you are already done. Otherwise if you need to access the contents of that string from the LabVIEW diagram, you have to copy the information of that string pointer into a real LabVIEW string.
One way to do that is to use the MoveBlock() C function export that LabVIEW exports itself. I have explained this several times here on this forum and a search for MoveBlock will without doubt uncover those posts.
Another slightly better way is to use the LStrPrintf() function that LabVIEW also exports. For that you configure a Call Library function as follows:
Library name: LabVIEW
Function name: LStrPrintf
Calling convention: C
Threading: both are possible but the function is thread safe so just use reentrant
return parameter: int32 (this is a possible LabVIEW manager error code)
1st parameter: LabVIEW string handle, passed by value
2nd parameter: C string pointer
3rd parameter: pointer sized integer, passed by valu
Wire an empty string constant to the first parameter.
Wire a constant containing the text "%s" without quotes to the 2nd.
Wire your string pointer to the 3rd
On return the function will either return 0 as return value and the contents of the string on the output side of the 1st parameter or a non-zero return value indicating an error.
04-15-2010 03:52 AM
1st parameter: LabVIEW string handle, passed by value
2nd parameter: C string pointer
3rd parameter: pointer sized integer, passed by value
I am running LabView 8.5, and I cannot see a "LabView String Handle" in the parameters tab? Are these "Types"?
04-15-2010 04:06 AM
04-15-2010 04:26 AM
ChristopherPovey wrote:1st parameter: LabVIEW string handle, passed by value
2nd parameter: C string pointer
3rd parameter: pointer sized integer, passed by value
I am running LabView 8.5, and I cannot see a "LabView String Handle" in the parameters tab? Are these "Types"?
You select a "String" datatype and then as subtype a "String Handle".
04-15-2010 04:32 AM
And parameter 3 is:
Type: Numeric
Data Type: Signed 8-bit Integer
Pass: Pointer to Value
???
Also the "problem" DLL function. Should that be set up as per "this little trick"?
Thanks.