LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

[HELP] Call Library Function Node...

Solved!
Go to solution

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?

Christopher Povey

Principle Test Systems Engineer for BAE Systems.
0 Kudos
Message 1 of 16
(5,575 Views)
With char* messageName [] you have an array of strings. You essentially have to pre-allocate the memory for the strings in LabVIEW. Otherwise, the DLL has no place to write the data, and your program crashes. LabVIEW does not store strings in the same way as C. Thus, the safest way to do this is to use a wrapper DLL. Search around, and you will see this topic has come up numerous times. However, if the strings can be limited in length, then you can try to use this little "trick".
0 Kudos
Message 2 of 16
(5,565 Views)

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!

Christopher Povey

Principle Test Systems Engineer for BAE Systems.
0 Kudos
Message 3 of 16
(5,549 Views)
That's still an array of strings. The example I linked to assumes the same length for all the strings. Is this true in your case? The use of char** implies they're probably not (though they still could be). If they're variable length you will have to write a wrapper DLL. Again, the links in the search I pointed you to discuss this issue.
0 Kudos
Message 4 of 16
(5,535 Views)

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...

Christopher Povey

Principle Test Systems Engineer for BAE Systems.
0 Kudos
Message 5 of 16
(5,519 Views)
Solution
Accepted by ChristopherPovey

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.

Rolf Kalbermatter
My Blog
Message 6 of 16
(5,511 Views)

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"?

Christopher Povey

Principle Test Systems Engineer for BAE Systems.
0 Kudos
Message 7 of 16
(5,491 Views)
I have knocked up a demo DLL to highlight the problem.  With a LabView DLL.  On success it should return "This is a Test!!!".
Christopher Povey

Principle Test Systems Engineer for BAE Systems.
0 Kudos
Message 8 of 16
(5,488 Views)

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".

Rolf Kalbermatter
My Blog
0 Kudos
Message 9 of 16
(5,482 Views)

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.

Christopher Povey

Principle Test Systems Engineer for BAE Systems.
0 Kudos
Message 10 of 16
(5,477 Views)