views:

1763

answers:

2

Hi

I want to use LabVIEW's Call Library Function Node to access a DLL function, and have this function return a string to displayed on my VI. How would I go about doing this? I am quite happy returning numbers from my DLL, but am really struggling to find any examples of how to return a string.

+1  A: 

I assume from your question that you already have a DLL that can return numbers to Labview. To return a string from the DLL, I have created a DLL with the following C++ function

void returnString(char myString[])
{
  const char *aString = "test string";
  memcpy(myString, aString, 12);
}

In Labview I then use the Call Library Function Node and configure it as follows

    Library Name or Path: c:\path\to\my\custom.dll
           Function Name: returnString
           Calling Convention: C

    Parameters: 
           Parameter: return type
                type: void

           Parameter: arg1
                type: String
                string format: C String Pointer

    Function prototype:
        void returnString(CStr arg1);

After connect the arg1 output in the block diagram to a string indicator and run. The string "test string" should appear in the front panel.

I tried to have the returnString function be of type CStr as in

CStr returnString()
{ ...
 }

but I got build errors when compiling the DLL project.

Update

Thanks to @bk1e comment don't forget to pre-allocate space in Labview for the string.

Azim
Thanks very much, that was exactly what I needed.
alex77
When use "C String Pointer" string format, your LabVIEW code is responsible for preallocating a large enough string to pass to the Call Library Function Node, or else your DLL may corrupt the LabVIEW heap. One way to allocate the string is to combine Initialize Array and Byte Array To String.
bk1e
+2  A: 

There are at least a few ways to return a string from a Call Library Function Node:

  1. Return a C string pointer from your DLL function, and configure the Call Library Function Node to have a return type of "C String Pointer". Note that the returned string must be valid after the function returns, so it can't be a pointer to a string allocated on the stack. It must be one of the following: allocated on the heap, statically allocated, a constant string literal, etc.

    It looks like examples/dll/regexpr/Regular Expression Solution/VIs/Get Error String.vi in the LabVIEW directory takes this approach.

  2. Allocate a string in your VI, pass it to the Call Library Function Node using a "C String Pointer" parameter as Azim suggested, and overwrite its contents in the DLL. One way to allocate the string is to use Initialize Array to create a u8 array of the desired size, and then use Byte Array To String to convert it to a string.

    Be sure that the string you pass in is large enough to hold the contents of your string, and make sure to pass the string length to the DLL so that it knows how large the buffer is. I believe that the default parameter is an empty string. Figuring out the right string length may require calling into the DLL twice, if your VI's first guess isn't large enough.

  3. Pass the string to the Call Library Function Node using a "String Handle" parameter, and use LabVIEW functions in your DLL to resize the string as necessary. This requires your DLL to be specifically designed to interface with LabVIEW and requires linking against a static library that is provided with LabVIEW.

    An example of this method ships with LabVIEW as examples/dll/hostname/hostname.vi.

bk1e
Using the second approach is similar to the way many Windows API functions work - first call with buffer size 0 to query the string length, second call with proper buffer. That way the DLL wouldn't be tied to LabVIEW, but could be used from other programming environments too.
mghie