LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

returning a C string from a win32 dll

Hi All,

I have a very simple VI form which calls a function in a dll, it
passes in as arguments an integer, 4 strings and it returns a C
string. The first 3 string parameters pass actual data as parameters
to the function. The forth string I use only as a pre-initialized
string pointer to use as the return string. Essentially my forth
string argument points to the same memory location as my returned
string. I allocate the memory for my forth parameter by creating a
constant array with a byte data type with 1024 bytes. Then I convert
it into the 4th string argument that I pass into the function (I
though this was one way to pre-allocate the memroy for the return
string). I can call this function continouesly for about a minute
and
there is no memory leak or any other slowdown or visible problems.
However, VI crashes when I close the project and exit.

Thank you in advance for your help

-Rafi
Message 1 of 15
(4,628 Views)
Please share your code with us - it is close to impossible to answer with
only an explanation of what your are doing

Are you by any chance using malloc ?

Regards

Klaus

"Rafi Ghazarian" wrote in message
news:a874ddd8.0110051803.17b9cb8c@posting.google.com...
> Hi All,
>
> I have a very simple VI form which calls a function in a dll, it
> passes in as arguments an integer, 4 strings and it returns a C
> string. The first 3 string parameters pass actual data as parameters
> to the function. The forth string I use only as a pre-initialized
> string pointer to use as the return string. Essentially my forth
> string argument points to the same memory location as my returned
> string. I allocate the memory for my forth param
eter by creating a
> constant array with a byte data type with 1024 bytes. Then I convert
> it into the 4th string argument that I pass into the function (I
> though this was one way to pre-allocate the memroy for the return
> string). I can call this function continouesly for about a minute and
> there is no memory leak or any other slowdown or visible problems.
> However, VI crashes when I close the project and exit.
>
> Thank you in advance for your help
>
> -Rafi
0 Kudos
Message 2 of 15
(4,627 Views)
"Klaus Vestergaard Kragelund" wrote in message news:...
> Please share your code with us - it is close to impossible to answer with
> only an explanation of what your are doing
>
> Are you by any chance using malloc ?
>
> Regards
>
> Klaus
>
> "Rafi Ghazarian" wrote in message
> news:a874ddd8.0110051803.17b9cb8c@posting.google.com...
> > Hi All,
> >
> > I have a very simple VI form which calls a function in a dll, it
> > passes in as arguments an integer, 4 strings and it returns a C
> > string. The first 3 string parameters pass actual data as parameters
> > to the function. The forth string I use only as a pre-initialized
> > string pointer to use as the return string. Essentially my forth
> > string argument points to the same memory location as my returned
> > string. I allocate the memory for my forth parameter by creating a
> > constant array with a byte data type with 1024 bytes. Then I convert
> > it into the 4th string argument that I pass into the function (I
> > though this was one way to pre-allocate the memroy for the return
> > string). I can call this function continouesly for about a minute and
> > there is no memory leak or any other slowdown or visible problems.
> > However, VI crashes when I close the project and exit.
> >
> > Thank you in advance for your help
> >
> > -Rafi

I don't use malloc on the string pointer which labview passes to the
dll. Here are the relevant source code snipets of my dll function:

CStr __stdcall SendRequest(long intComPort, CStr strID, CStr strType,
CStr strParam, CStr strData, CStr strReturn)
{
LPVOID lpMsgBuf;
char strErrMsg[1024];
char strComPortName[25];
char strRequestMessage[50];
char strCheckSum[2];

strcpy(strReturn, "");

sprintf(strErrMsg, "Here is the function input: ComPort=%d, ID=%d,
Type=%s, Parameter=%d.\n", intComPort, strID, strType, strParam);
Log(strErrMsg);

//Validate Input
if (!ValidateInput(strID, strType, strParam, strData, strErrMsg))
{
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0,NULL);
sprintf(strReturn,"%s:\n%s\n", strMessage, lpMsgBuf);
LocalFree( lpMsgBuf );
Log(strReturn);
return strReturn;
}

HANDLE hCom;

//construct the ComPort name
sprintf(strComPortName, "Com%d", intComPort);
hCom = OpenCommunicationPort(strComPortName, strErrMsg);

if (hCom != INVALID_HANDLE_VALUE)
{
//Now consruct the read/write request and send it to the com port
//Here is the format of the request message: $[intID]01
sprintf(strRequestMessage, "$%02d01", strID);

if (strcmp(strType, "R") == 0)
{
strcpy(strCheckSum, "CC");
int i = strlen(strCheckSum);

//It's a read request
sprintf(strRequestMessage, "%s%s%02d%s%c", strRequestMessage,
strType, strParam, strCheckSum, 13 /*CR*/);
unsigned long dwWritten;
if (!WriteFile(hCom, strRequestMessage, strlen(strRequestMessage),
&dwWritten, NULL)) {
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL,
SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0,NULL);
sprintf(strReturn,"%s:\n%s\n", strMessage,
lpMsgBuf);
LocalFree( lpMsgBuf );
Log(strReturn);
return strReturn; }
}
else
{
//it's a write request
}

CloseHandle(hCom);
}
else
{
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0,NULL);
sprintf(strReturn,"%s:\n%s\n", strMessage, lpMsgBuf);
LocalFree( lpMsgBuf );
Log(strReturn);
return strReturn;
}


return strReturn;
}
0 Kudos
Message 5 of 15
(4,627 Views)
"Rafi Ghazarian" wrote in message
news:a874ddd8.0110070012.718c25e6@posting.google.com...
> "Klaus Vestergaard Kragelund" wrote in message
news:...
> > Please share your code with us - it is close to impossible to answer
with
> > only an explanation of what your are doing
> >
> > Are you by any chance using malloc ?
> >
> > Regards
> >
> > Klaus
> >
> > "Rafi Ghazarian" wrote in message
> > news:a874ddd8.0110051803.17b9cb8c@posting.google.com...
> > > Hi All,
> > >
> > > I have a very simple VI form which calls a function in a dll, it
> > > passes in as arguments an integer, 4 strings and it returns a C
> > > string. The first 3 string parameters pass actual data as parameters
> > > to the function. The forth string I use only as a pre-initialized
> > > string pointer to use as the return string. Essentially my forth
> > > string argument points to the same memory location as my returned
> > > string. I allocate the memory for my forth parameter by creating a
> > > constant array with a byte data type with 1024 bytes. Then I convert
> > > it into the 4th string argument that I pass into the function (I
> > > though this was one way to pre-allocate the memroy for the return
> > > string). I can call this function continouesly for about a minute and
> > > there is no memory leak or any other slowdown or visible problems.
> > > However, VI crashes when I close the project and exit.
> > >
> > > Thank you in advance for your help
> > >
> > > -Rafi
>
> I don't use malloc on the string pointer which labview passes to the
> dll. Here are the relevant source code snipets of my dll function:
>
> CStr __stdcall SendRequest(long intComPort, CStr strID, CStr strType,
> CStr strParam, CStr strData, CStr strReturn)
> {
> LPVOID lpMsgBuf;
> char strErrMsg[1024];
> char strComPortName[25];
> char strRequestMessage[50];
> char strCheckSum[2];
>
> strcpy(strReturn, "");
>
> sprintf(strErrMsg, "Here is the function input: ComPort=%d, ID=%d,
> Type=%s, Parameter=%d.\n", intComPort, strID, strType, strParam);
> Log(strErrMsg);
>
> //Validate Input
> if (!ValidateInput(strID, strType, strParam, strData, strErrMsg))
> {
> FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
> FORMAT_MESSAGE_FROM_SYSTEM |
> FORMAT_MESSAGE_IGNORE_INSERTS,
> NULL,
> GetLastError(),
> MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
> (LPTSTR) &lpMsgBuf,
> 0,NULL);
> sprintf(strReturn,"%s:\n%s\n", strMessage, lpMsgBuf);
> LocalFree( lpMsgBuf );
> Log(strReturn);
> return strReturn;
> }
>

Off-hand - in the line just above "return strReturn". You are returning the
pointer of strReturn. But shouldn't the prototype be:

> CStr __stdcall SendRequest(long intComPort, CStr strID, CStr strType,
> CStr strParam, CStr strData, CStr *strReturn)

and without the return of strReturn. You have allready supplied the pointer
in the last argument - so why are you also using "Return" ?. I don't know
the CStr type - but I'm guessing it is a string.

If this doesn't help - please supply your call to the SendRequest function
for further help. Or even better place the posting on comp.lang.c - they
will certainly be able to help you

regards

Klaus


> HANDLE hCom;
>
> //construct the ComPort name
> sprintf(strComPortName, "Com%d", intComPort);
> hCom = OpenCommunicationPort(strComPortName, strErrMsg);
>
> if (hCom != INVALID_HANDLE_VALUE)
> {
> //Now consruct the read/write request and send it to the com port
> //Here is the format of the request message: $[intID]01
> sprintf(strRequestMessage, "$%02d01", strID);
>
> if (strcmp(strType, "R") == 0)
> {
> strcpy(strCheckSum, "CC");
> int i = strlen(strCheckSum);
>
> //It's a read request
> sprintf(strRequestMessage, "%s%s%02d%s%c", strRequestMessage,
> strType, strParam, strCheckSum, 13 /*CR*/);
> unsigned long dwWritten;
> if (!WriteFile(hCom, strRequestMessage, strlen(strRequestMessage),
> &dwWritten, NULL)) {
> FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
> FORMAT_MESSAGE_FROM_SYSTEM |
> FORMAT_MESSAGE_IGNORE_INSERTS,
> NULL,
> GetLastError(),
> MAKELANGID(LANG_NEUTRAL,
> SUBLANG_DEFAULT),
> (LPTSTR) &lpMsgBuf,
> 0,NULL);
> sprintf(strReturn,"%s:\n%s\n", strMessage,
> lpMsgBuf);
> LocalFree( lpMsgBuf );
> Log(strReturn);
> return strReturn; }
> }
> else
> {
> //it's a write request
> }
>
> CloseHandle(hCom);
> }
> else
> {
> FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
> FORMAT_MESSAGE_FROM_SYSTEM |
> FORMAT_MESSAGE_IGNORE_INSERTS,
> NULL,
> GetLastError(),
> MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
> (LPTSTR) &lpMsgBuf,
> 0,NULL);
> sprintf(strReturn,"%s:\n%s\n", strMessage, lpMsgBuf);
> LocalFree( lpMsgBuf );
> Log(strReturn);
> return strReturn;
> }
>
>
> return strReturn;
> }
0 Kudos
Message 6 of 15
(4,618 Views)
Rafi;

Sorry the following is a question about your question 🙂

Your situation sound similar to previous experiences I had working with dll's. In your case, do you have to "initialize an engine" or "load resources" or something like that before calling any function in the dll?

Enrique
www.vartortech.com
0 Kudos
Message 3 of 15
(4,625 Views)
Enrique wrote in message news:<5065000000050000008A450000-1002247793000@exchange.ni.com>...
> Rafi;
>
> Sorry the following is a question about your question 🙂
>
> Your situation sound similar to previous experiences I had working
> with dll's. In your case, do you have to "initialize an engine" or
> "load resources" or something like that before calling any function in
> the dll?
>
> Enrique

No I don't, I don't know if you would consider opening the serial port
as loading a resource, but I do open the serial port, and I close it
before the dll function returns.
0 Kudos
Message 4 of 15
(4,624 Views)
we have same problem!
someone helped you? what's the solution?
thanks!
0 Kudos
Message 7 of 15
(4,612 Views)
I am in the same trouble. I call an external WIN 32 library. But after the calling, the labview crashes. I am trying to get an string from the external function call.

How can I solve it?

Thank you in advance.


0 Kudos
Message 8 of 15
(4,305 Views)


@gborges wrote:
I am in the same trouble. I call an external WIN 32 library. But after the calling, the labview crashes. I am trying to get an string from the external function call.

How can I solve it?


By making sure your Call Library Node configuration matches the actual function interface you try to call. There is nothing else to it! Without any more information this is all anybody could possibly recommend you.

Rolf Kalbermatter
Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 9 of 15
(4,291 Views)
I am trying to call a external WIN 32 library in which one of its parameters is a struct. By this way, I follow some advices and so I build a cluster with all the elements that the library's function needs.

All the parameters that I pass to the function are correct. I checked it, exporting the code, so it is all ok with the call.

I noted that the values that are integers, I can get them back without any problem. But the parameter that returns a string, I have this problem, it always returns nothing, but there is data to be returned.

Maybe I have to allocate some space to this data, but how can I do it?

Thank you in advance.
0 Kudos
Message 10 of 15
(4,268 Views)