LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

C and labview examples

I have a few questions with .dll files in C and C++ and labview so bear with me. I have a C++ file that I am trying to make accesible through labview, is it possible to export member functions in C++ using the _declspec(dllexport). Another way I am going about this is trying to convert the file into C and I was wondering if anybody had knew of any examples whatsoever on serial communications in C and labview that I can take a look at. I tried writing a function in C using the HANDLE declaration, but I keep getting back weird things in Labview. I sent a command to erase the device and it should have said "Cannot Erase Flash" since the device was not powered on. Instead it said "Successfully Erased." Another problem I am having is that I am trying to return an array of characters to labview but i keep getting error messages in labview. I've read a lot of documents on it but including the one "External Code in Labview" but its not helpine me. Help!!!!
 

HERE is my erase code:

 DWORD iBytesWritten;
 DWORD iBytesRead;
 BOOL bWriteRC;
 BOOL bReadRC;
 char *sBuffer;

 bWriteRC = WriteFile(a,"E\r",2,&iBytesWritten,NULL);
 if (bWriteRC){
    ;    //do nothing
 }
 else
  return "Cannot Erase the Flash";
 bReadRC = ReadFile(a,&sBuffer,20,&iBytesRead,NULL);
 if (bReadRC){
  return sBuffer;    //do nothing
 }
 else
  return "Cannot Read the Flash";

Message Edited by Newguy100 on 07-30-2005 06:30 PM

Message Edited by Newguy100 on 07-30-2005 06:31 PM

0 Kudos
Message 1 of 12
(4,608 Views)
Can i do this:
C++:
 void something :: anything(void)
 
using _declspec:
void _declspec(dllexport) something ::anything(void)
 
Is this ok?
0 Kudos
Message 2 of 12
(4,588 Views)

Hi,

When writing a dll in C++ for calling from LabVIEW, you need to wrap your function declaration in extern C clause so that the C++ compiler would not decorate the function name in the object code (see page 30 of 'Using External Code with LabVIEW' manual) . Also fro exporting the DLL functions you would need to use _declspec(dllexport).

 

Here is an example for serial communication using C++.

http://sine.ni.com/apps/we/niepd_web_display.display_epd4?p_guid=B45EACE3DFE756A4E034080020E74861&p_...

Hope this helps.

Ankita

0 Kudos
Message 3 of 12
(4,557 Views)
Thanks, this may be just the thing that will help fix the problem. Another thing, how do I return an array of characters from C into labview?

Message Edited by Newguy100 on 08-01-2005 04:50 PM

0 Kudos
Message 4 of 12
(4,557 Views)

What about spending like 10min to read 'Using External Code with LabVIEW'. 😉

cheers

Pawel

0 Kudos
Message 5 of 12
(4,532 Views)
I have read the document and it just gives me more questions than answers.
0 Kudos
Message 6 of 12
(4,519 Views)
NewGuy,

You need to post you function declaration. Without that, it's very difficult to tell what you're doing.
Having said that:

return "Cannot Erase the Flash"

is a really bad idea. Strings (or, more specifically string pointers) are almost never returned in the return value of a function in C/C++. It's even worse when you try to return this to LabVIEW, since LabVIEW can't handle strings as return function. This is because LabVIEW must manage the memory associated with any string data it manipulates.

Instead, you should consider writing a function like this:

int FillString(char* pBuffer, int* pLen)
{
  const char* kTest="Hello, world.";
  int retval=0;
  
  //If the length is zero, or the buffer is NULL, just return the necessary length
  if(*pLen==0 || pBuffer==NULL)
  {
    *pLen=strlen(kTest)+1;
    return 0;
  }

  //If the buffer is too small, return an error after copying everything we can.
  if(*pLen-1 < strlen(kTest)
    retval=1;

  *pLen=min(*pLen-1,strlen(kTest))
  strncpy(pBuffer, kTest, *pLen);
  //strncpy doesn't append a null terminator, do so now.
  pBuffer[*pLen]=0;
  
  return retval;
}

This code allows LabVIEW to manage the buffer. Make sure in your VI that you initialize the string to a certain length and then pass it to the DLL by pointer. I believe that the External Code Reference Manual discusses this. Also configure the call to pass the string length by pointer. This code is robust in that it allows for error checking and also allows the function to return the necessary buffer size so that the caller can allocate it and then call the function again. Depending on your application, you may not need all the complication of this (for instance, if your strings are guaranteed to be a certain maximum length).

0 Kudos
Message 7 of 12
(4,520 Views)

Here is my function declaration:

_declspec(dllexport) char* EraseCmd(void){

What i was thinking about doing was returning a statement in labview. I wanted to compare the statement in labview to what was read in the serial port and if they match they should move on,otherwise they should stop.  I guess I could do the same thing in C using a strcmp and have it return a specific integer if they match or not.

0 Kudos
Message 8 of 12
(4,515 Views)
I converted the .dll into an executeable file, made some changes and ran it. It seems to work. Now my question is is how different is the .dll to the executable file because it does work as the way it does in the executeable file. I have a guess that it might be due on my part and I just want to know if it is correct. I created two .dll files, the original and the new modified one. Both of these files use serial port communication. However, in Labview, when I do a Call Library Node function, I open the port in the original .dll but I use one of the functions in the modified .dll file. When I run it, it freezes. Is it because I open a serial port in one file and the other file doesn't recognize it? What I mean by that is do I have to basically use one file for serial communication?

 

Message Edited by Newguy100 on 08-12-2005 04:41 PM

0 Kudos
Message 9 of 12
(4,479 Views)
NewGuy,

Your last message wasn't very clear. Please be more specific in what you have done.

1) There is minimal difference between a DLL and an executable, the biggest of which is that an executable has a main entry point, where as a DLL does not (at least if we ignore DLLMain, which generally has a slightly different purpose than an exe main).

2) I don't believe that there should be any problem with making serial calls from multiple DLLs in general. However, if the serial calls that you are using make use of global variables, thread-local storage, or a couple of other gotchas, then there could be a problem.

But, one has to ask why. Why break this code up into two DLLs? I'm not saying there isn't a good reason, but I can't think of any.

Perhaps if you posted some salient excerpts of you code we could help you more.

Jason
0 Kudos
Message 10 of 12
(4,439 Views)