LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

C string to LabView string

Hi

I'd like to know if someone may tell me how to convert a C string to LabView String, because I need to use a function in C which is on a shared library .so, that function returns a "char *parameter", and I want to show that string to LabView through a string indicator of LabView. I found a CIN which receives a LStrHandle and convert to CStr string and it returns it as LStrHandle again. I modified that CIN in order to work as I wanted, but it didn't work, LabView crashed everytime I run this modified CIN, here is my code:
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
/*
 * CIN source file 
 */
 
#include "extcode.h"
 
/* stubs for advanced CIN functions */
 
UseDefaultCINInit
UseDefaultCINDispose
UseDefaultCINAbort
UseDefaultCINLoad
UseDefaultCINUnload
UseDefaultCINSave
 
CIN MgErr CINRun(CStr str_orig, LStrHandle str_mod);
 
CIN MgErr CINRun(CStr str_orig, LStrHandle str_mod)
{
 
    int32 len;
    MgErr err = bogusError; /* bogusError is miscellaneous     */
                          /* error code defined in extcode.h */
     
    len = StrLen(str_orig);
 
    /* resize modified LV string to accomodate c string */
    if (err = NumericArrayResize(uB, 1L,(UHandle *)&str_mod, len))
        goto out;
 
    /* update the length of the modified LV string */
    LStrLen(*str_mod) = len;
 
    /* move len bytes from cstring to modified LV string */
    MoveBlock(&str_orig, LStrBuf(*str_mod), len);
 
    return noErr;
 
out:
    return err;
}
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

So where is the error, or is there another way to do this?

I've tried to pass the output of the library function (char *) to a LabView string indicator directly, there is no error, but the string showed in the LabView indicator is wrong, is just garbage ... By the way I'm very newbie in LabView :s...

Thanks in advanced

Message Edited by nmxnmx on 01-30-2006 02:32 PM

Message Edited by nmxnmx on 01-30-2006 02:34 PM

0 Kudos
Message 1 of 14
(6,437 Views)
You shouldn't need the CIN to get the string. I created a simplistic DLL with a single function that returned a char * as the return value of the function.  Excerpt:

#ifdef RETURNSTRING_EXPORTS
#define RETURNSTRING_API __declspec(dllexport)
#else
#define RETURNSTRING_API __declspec(dllimport)
#endif

RETURNSTRING_API char * fnReturnString(void)
{
    return "this is a test";
}

In LabVIEW I just used the "Call Library Function" as shown in attached image.

Perhaps if you post the DLL with the function you're trying to call along with your VI we may be of more help.

Message Edited by smercurio_fc on 01-30-2006 03:36 PM

0 Kudos
Message 2 of 14
(6,408 Views)
Hi, well basically the function in the library function is like this:

char *test_string()
{
    char string_data[MAXDATA]; /*MAXDATA previously defined*/
    strcpy(string_data, "string_test");
    return string_data;
}

when I run that and I wired the "Call library function node" with a Labview String indicator directly I got garbage like it show the pic:

Message Edited by nmxnmx on 01-30-2006 04:38 PM

Message Edited by nmxnmx on 01-30-2006 04:40 PM

0 Kudos
Message 3 of 14
(6,399 Views)
I didn't have a problem with that either. I also created this variant:

__declspec(dllexport) void fnReturnString3(char * data)
{
    strcpy(data, "string_test");
}

In LabVIEW I created a buffer string to pass to the function call and got "string_test" back. Maybe there's a problem with the way the DLL is being built?

You should take a look in the LabVIEW install directory in the "examples\dll\data passing" directory. There you will find a Visual Studio project that's a DLL and a LabVIEW library with tons of examples of calling a DLL with various parameters.
0 Kudos
Message 4 of 14
(6,385 Views)


@smercurio_fc wrote:
I didn't have a problem with that either. I also created this variant:

__declspec(dllexport) void fnReturnString3(char * data)
{
    strcpy(data, "string_test");
}

In LabVIEW I created a buffer string to pass to the function call and got "string_test" back. Maybe there's a problem with the way the DLL is being built?

You should take a look in the LabVIEW install directory in the "examples\dll\data passing" directory. There you will find a Visual Studio project that's a DLL and a LabVIEW library with tons of examples of calling a DLL with various parameters.


The problem is probably the return value of the function that is a string. In older LabVIEW versions (<6.0 you couldn't configure the CLN to do that.

Rolf Kalbermatter.
Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 5 of 14
(6,373 Views)
Well my version of LabView is 7.1, and I'm getting the same problem Smiley Indifferent and if I can't pass directly a C string to LabView String Indicator, how could I do to get this ?

Message Edited by nmxnmx on 01-31-2006 11:29 AM

0 Kudos
Message 6 of 14
(6,360 Views)
Generally you don't want a function to return a char *, but rather have a char * as one of the arguments.

I.e.,
you want something like this:
    int myFunction(char * data)
rather than this:
    char * myFunction()

The reason is that the first method returns the address of the first character rather than a "string" like in VB. In LabVIEW you create a buffer to hold the data and you pass this buffer to the function. Again, the examples in the LabVIEW "examples\dll\data passing" directory are quite clear and I would recommend that you use those as a template. Attached is an example that shows different methods.

-Saverio


Message 7 of 14
(6,347 Views)
Thanks smercurio, but don't you think I don't want to take your recomendation of viewing the examples you mentionated, but I'm not using LabView for Windows, I'm using LabView for Linux, so those examples aren't in this installation..

But I changed this part of my code: "char data_string[MAXDATA];" for "char *data_string;" and "strcpy(data_string, "string_test");" for "data_string = "string_test";" and worked :mansurprised:, I don't know why exactly if I think that It's supposedly the same thing "char data_string[MAXDATA]" and "char *data_string", in both cases the value returned (char *funtion_name() ) is a pointer to char, isn't it ?
0 Kudos
Message 8 of 14
(6,341 Views)
This is one of the many places where c gets ugly.  When you do this:
char *test_string()
{
    char string_data[MAXDATA]; /*MAXDATA previously defined*/
    strcpy(string_data, "string_test");
    return string_data;
}

The variable string_data is in scope ( exists ) only between the curly braces.  strcpy copies the bytes from the literal to the location allocated to string_data.  Passing the address of this variable outside of this function is bad because the compiler is allowed to allocate that variables memory to something else once it passes out of scope.

Doing this:
RETURNSTRING_API const char * fnReturnString(void)
{
    return "this is a test";
}

creates a literal in the executable.  The return statement passes the address of the literal up the callstack.  I have added in the const directive so the compiler can warn you of attempts to alter memory that is not guaranteed to be writable.

Your changes worked because this is essentially what you are doing.

char *test_string()
{
    char *data_string;  // Create a location to hold the address of a character (pointer to char)
    data_string = "string_test";  // Copy the address of the first charater of "string_test" to data_string
    return data_string;  // Return a copy of the contents of data_string (address of the first character of "string_test")
}

In this case you are returning a pointer to the literal "string_test". 

The best method is:

__declspec(dllexport) void fnReturnString3(char * data)
{
    strcpy(data, "string_test");
}

because now the caller is responsible for managing the buffer it uses to handle the string and can do what it wants with it.

Yes, both are returning a pointer to char, but one returns the address of an out of scope variable and the other returns the address of a literal.

Here's a few sections you should read:
C faq question 7.5a
C faq question 7.5b
and
A long discussion on C strings: pointers vs arrays
----
I am the founder of CnCSoftwareSolutions. When not cleaning up baby drool, I write about test data or work on Vision, a tool for understanding your test data. Visit me at www.cncsoftwaresolutions.com
Message 9 of 14
(6,329 Views)
Thanks you very much for your explanation daijoubu, and yes It's for sure I will read the links you gave me... Thanks very much again Smiley Happy
0 Kudos
Message 10 of 14
(6,315 Views)