LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

labview dll with string arrays to c++

Solved!
Go to solution

I am looking to use labview to extract a gas list from a txt file and then transfer this gas list to a C++ program. 

 

I thought it would be easiest to just transfer the gas list an array of strings from the labview dll to my C++ program.  However, I am not able to output the gas list using arrays; I am only able to output the pointer, not the string that the pointer references.  Obviously, I have a syntactical issue with my output methodology.

 

I have no problem outputting the gas list via a simple string.  However, the single string approach requires multiple calls to the relevant dll.

 

My code is based upon sample labview dll for C++ routines entitled Calling Labview DLL in Visual C++ That Passes Array Handles by Reference  (http://zone.ni.com/devzone/cda/epd/p/id/1518). 

 

I am quite certain that what I am trying to do is quite simple for an experienced Labview programmer.  However, my labview and C/C++ and experience is limited.

 

I thank you in advance for your assistance.

 

My labview and C code is in the attached zip file.  However, the basic C code and the resultant output are as follows:

 

 

// Call DLL.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "Array_Multiply.h" #include <stdio.h> #include <string> #include <iostream> #include <fstream> #include <cstring> using namespace std; int main(int argc, char* argv[]) { TD1Hdl handle_var3; long temp; char stringout[25]; temp=25; handle_var3 = (TD1**)DSNewHandle(sizeof(TD1)); // initialize sizes (*handle_var3)->dimSize = 1; // // Gasstring is a function that outputs a Labview array of strings. // However, I can't make this work. All I am doing is outputting // memory addresses. // Gasstring(&handle_var3); cout << "\n gasstring " << *handle_var3; cout << "\n gasstring " << handle_var3; cout << "\n gasstring " << (*handle_var3)->String[0]; //cout << "\n gasstring " << (*handle_var4)->Numeric[0]); // // Gasstring3 is just a single string. There are no issues outputting // this string. // Gasstring3(stringout,temp); cout << "\n gasstring3 " << stringout; cout << " \n enter in number "; cin >> temp ; return 0; }

The output of my source code is:

 

Output.JPG

0 Kudos
Message 1 of 8
(5,112 Views)

I had a similar issue some years ago.

I solved the problem by concatenating all items in a single string, with newlines between them.

On the caller's side I tokenized them back into an array of strings.

 

0 Kudos
Message 2 of 8
(5,098 Views)

Thanks for the information.  However, is there anyway to make my C++ code work ?  It would seem that getting the string arrays to transfer from labview to C++ correctly is the more elegant method - but is this even possible ?

 

I can't help but think that the issue is I haven't set something up correctly (memory management and / or correctly deferencing the pointers so as to obtain the actual strings).

 

I have relisted my code, as it is now screwed up in the original posting.

 

Thanks,

 

RW

 

// Call DLL.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "Array_Multiply.h" #include <stdio.h> #include <string> #include <iostream> #include <fstream> #include <cstring> using namespace std; int main(int argc, char* argv[]) { TD1Hdl handle_var3; long temp; char stringout[25]; temp=25; handle_var3 = (TD1**)DSNewHandle(sizeof(TD1)); // initialize sizes (*handle_var3)->dimSize = 1; // // Gasstring is a function that outputs a Labview array of strings. // However, I can't make this work. All I am doing is outputting // memory addresses. // Gasstring(&handle_var3); cout << "\n gasstring " << *handle_var3; cout << "\n gasstring " << handle_var3; cout << "\n gasstring " << (*handle_var3)->String[0]; // // Gasstring3 is just a single string. There are no issues outputting // this string. // Gasstring3(stringout,temp); cout << "\n gasstring3 " << stringout; cout << " \n enter in number "; cin >> temp ; return 0; }

 

0 Kudos
Message 3 of 8
(5,094 Views)
Solution
Accepted by topic author RamblingWreck

I think I have figured something out 🙂

 

cout  << "\n gasstring  " << LStrBuf(*(*handle_var3)->String[0]);

 

There are some useful macros for LStrHandles in "extcode.h", LStrBuf is one of them.

 

It seems there are no issues with the memory management, you did it right.

 

Message 4 of 8
(5,084 Views)

THANK YOU VERY MUCH !!

 

This was driving me nuts.  I knew I was close, but I also knew that I was not well versed enough in both Labview and C++ to totally figure out the issue on my own.

 

This gets me 80% towards where I need to be.  I still have a minor issue with another related floating point array, but  I think I can figure that one out myself.

 

I don't know if you are located in the US, but if you are, please have a happy fourth of July !

 

RW

0 Kudos
Message 5 of 8
(5,076 Views)

Last question.

 

I had also taken the original example problem (http://zone.ni.com/devzone/cda/epd/p/id/1518) and changed it from an array with a dimension of 1 (which is really a scalar) to an array with dimension five.  However, it looks like unless I change the array dimension from 1 to 5 in the Array_Mulitpy.h file, then I run into memory allocation issues. 

 

I say this because all the sample labview code does is create two arrays with different numbers.  It then multiplies the first array by 2, stuffs the result in the second array and returns the second array.

 

The values for the second array do not come back with correct values.  In fact, the values for the second array can change depending upon how / when I execute the code.  This indicates to me (admittedly a novice labview / C++ programmer) that there are some memory leak issues. 

 

I would like to understand this issue before I go any further - just so I don't create huge problems for myself later on.  (I know that I should NOT be changing the dimension to 5 in Multiply_Array.h)

 

My sample code and the corresponding results are below.  I have also attached a zip file of all the C++ code and the labview vi's and dll.

 

Again, many thanks for your assistance.

 

RW

 

// Call DLL.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "Array_Multiply.h" #include <stdio.h> #include <string> #include <iostream> #include <fstream> #include <cstring> using namespace std; int main(int argc, char* argv[]) { TD1Hdl handle_var; TD1Hdl handle_var2; long temp; temp=25; // use DSNewHandle instead of malloc to allocate memory handle_var = (TD1**)DSNewHandle(sizeof(TD1)); handle_var2 = (TD1**)DSNewHandle(sizeof(TD1)); // initialize sizes (*handle_var)->dimSize = 5; (*handle_var2)->dimSize = 5; // initialize values of 1st elements (*handle_var)->Numeric[0] = 1; (*handle_var)->Numeric[1] = 2; (*handle_var)->Numeric[2] = 3; (*handle_var)->Numeric[3] = 4; (*handle_var)->Numeric[4] = 5; // (*handle_var2)->Numeric[0]= 10; (*handle_var2)->Numeric[1]= 20; (*handle_var2)->Numeric[2]= 30; (*handle_var2)->Numeric[3]= 40; (*handle_var2)->Numeric[4]= 50; printf("handle_var2 before call to DLL:\t%f\n\n", (*handle_var2)->Numeric[0]); printf("handle_var2 Before call to DLL:\t%f\n\n", (*handle_var2)->Numeric[1]); printf("handle_var2 Before call to DLL:\t%f\n\n", (*handle_var2)->Numeric[2]); printf("handle_var2 Before call to DLL:\t%f\n\n", (*handle_var2)->Numeric[3]); printf("handle_var2 Before call to DLL:\t%f\n\n", (*handle_var2)->Numeric[4]); printf("\n\n handle_var Before call to DLL:\t%f\n\n", (*handle_var)->Numeric[0]); printf("handle_var Before call to DLL:\t%f\n\n", (*handle_var)->Numeric[1]); printf("handle_var Before call to DLL:\t%f\n\n", (*handle_var)->Numeric[2]); printf("handle_var Before call to DLL:\t%f\n\n", (*handle_var)->Numeric[3]); printf("handle_var Before call to DLL:\t%f\n\n", (*handle_var)->Numeric[4]); // // the DLL multiplies each element of the input array by 2 and passes // that value to the corresponding index of the output array // Array_Multiply(&handle_var, &handle_var2); // printf("\n\n handle_var2 After call to DLL:\t%f\n\n", (*handle_var2)->Numeric[0]); printf("handle_var2 After call to DLL:\t%f\n\n", (*handle_var2)->Numeric[1]); printf("handle_var2 After call to DLL:\t%f\n\n", (*handle_var2)->Numeric[2]); // // Note that the output of Array_Multipy for elements 4 and 5 // is only correct if I set Numeric to Numeric[5] in the corresponding // defintion of TD1 in Array_Mulitiply.h. With Numeric set to Numeric[1], // elements 4 and 5 comeback as 20 and 0. With Numeric set to Numeric[5}, // elements 4 and 5 come back as 8 and 10 - which is what they should be. // printf("handle_var2 After call to DLL:\t%f\n\n", (*handle_var2)->Numeric[3]); printf("handle_var2 After call to DLL:\t%f\n\n", (*handle_var2)->Numeric[4]); cout << " \n enter in number "; cin >> temp ; return 0; }

 

error3.JPG

0 Kudos
Message 6 of 8
(5,067 Views)

Me again 🙂

 

This time it's a memory allocation issue:

After changing memory size like

 

(*handle_var)->dimSize = 5;

 

your numeric array size hasn't changed yet,

so you can still store only one element in it.

 

To resize it, you have to call another LabVIEW memory management function,

NumericArrayResize() . Unfortunately NumericArrayResize() crashes if you call

it before initializing the LabVIEW runtime. I found a workaround but I don't know

whether it's the clean way to fix that issue. Here is it (error checking omitted):

 

// call LVDLLStatus() exported by any LabVIEW built DLL to initialize runtime

char err[128];
LVDLLStatus(err, 128, NULL);

 

// use DSNewHandle instead of malloc to allocate memory
handle_var = (TD1**)DSNewHandle(sizeof(TD1));
handle_var2 = (TD1**)DSNewHandle(sizeof(TD1));
 
// initialize arrays
NumericArrayResize(fD, 1L, (UHandle*)&handle_var, 1);
NumericArrayResize(fD, 1L, (UHandle*)&handle_var2, 5);

 

// update sizes

(*handle_var)->dimSize = 1;
(*handle_var2)->dimSize = 5;

 

...

 

BTW, I think you're much better at C++ than many people that use it 🙂

 

0 Kudos
Message 7 of 8
(5,046 Views)

candidus:

 

Many thanks for all your help.  I cetainly have enough information to proceed full speed ahead.

 

Again, many thanks and hopefully one day I can return the favor.

 

RW

0 Kudos
Message 8 of 8
(5,015 Views)