Jump to content

calling Labview DLL from VB.NET


Recommended Posts

I have tasks to call various LabView DLLs from my VB.NET application.

I found  the LVCalculator.dll example on NI website to call Labview DLL from VB.net. It shows how to declare the DLL and call in VB.net and

 

Declare Auto Function Calculator Lib "..LabVIEWLVCalculator.dll" (ByVal val1 As Double, ByVal val2 As Double, ByVal Op As Integer) As Double

 

Result.Text = Calculator(System.Double.Parse(Operand1.Text), System.Double.Parse(Operand2.Text), add)

 

This example works fine.

 Unfortunately, all examples I found have parameteres with standard data type such as Integer, Double or String. However in my DLL I have a parameter LVRefNum *VISAIN and *VISAOUT .

 

void __cdecl LCDColor(LVRefNum *VISAIN, uint16_t LCDColor2, TD1 *errorInNoError, LVRefNum *VISAOUT, char OutputString[], TD1 *errorOut, int32_t len);

 

 These parameters in my DLL are a Com Port numbers, which Labview VI uses to communicate with the controlled hardware. When this VI runs as standalone program in with Labview GUI the COM port is selected from the menu. But when I call this VI as a DLL, I need to pass my COM port number via the parameter LVRefNum *VISAIN (VISAOUT).  And I could not figure out what data type and format to use to make  DLL understand it.

Link to comment

I'm no expert in VB but looking at the VISA programming manual, references are usually passed as

 

Byval Value& (notice the ampersand)

 

e.g. 

 

C Syntax:
ViStatus viGpibSendIFC(ViSession vi)


Visual Basic Syntax:
viGpibSendIFC&(ByVal vi&)

 

The C pointer (asterisk) makes me tentative, however, since it could be a ByRef. But it is unusual.

Hopefully Rolf will be along to answer definitely (he's the guru on this kind of stuff, I tend to work the other way around - Labview->C)

Edited by ShaunR
Link to comment

Thanks for reply. Actually I need to find out what a real value I should pass via the parameter LVRefNum *VISAIN. Let's say If I need to tell the DLL using Com Port 1, what should be in my calling variable that DLL understands: 1 or COM1 or "COM1" or "1" or anything else ? I don't create this DLL, I don't program Labview. I only get a header file from Labiew project with calling parameters knowing that this is a variable for a Com Port.

 

Thanks.

Link to comment

Those refnum types will all be 32-bit integers in VB.Net. Just declare variables of type "int". In the case of the modifiable refnums, use "ref int".

 

In answer to your second question of how you get valid values for those as inputs, one of the other functions will be supplying those values. There should be some function on your LV DLL like "Open Port" or "Create XYZ Reference" that only has those refnums as outputs. You'll pass the result to the other functions.

Link to comment
Thanks for reply. Actually I need to find out what a real value I should pass via the parameter LVRefNum *VISAIN. Let's say If I need to tell the DLL using Com Port 1, what should be in my calling variable that DLL understands: 1 or COM1 or "COM1" or "1" or anything else ? I don't create this DLL, I don't program Labview. I only get a header file from Labiew project with calling parameters knowing that this is a variable for a Com Port.

 

Thanks.

 

You need to call an initialising function first and it will return the reference that you can then pass to your other functions.

 

Using the VISA example again, there is a viOpen function

 

C Syntax

ViStatus viOpen(ViSession sesn, ViRsrc rsrcName, ViAccessMode accessMode, ViUInt32 openTimeout, ViPSession vi)

Visual Basic Syntax

viOpen&(ByVal sesn&, ByVal rsrcName$, ByVal accessMode&,ByVal openTimeout&, vi&)

 

 

It takes as an argument a string which is the resource name - rsrcName$ -  (e.g. "Com1"). and returns the session value which is the vi&.

 

It is the vi& that is passed to the other functions.

 

Your DLL should have a similar function that takes a resource name string and passes back a LVRefNum which you can then pass into your  other function calls.

Edited by ShaunR
Link to comment

Thanks to all of you. It looks like you talking a case if I need to get resource name from this DLL. Actually, my VB program already knows resource name ("COM1") and should pass it to DLL. I will try to send it just as a string "COM1" and see if DLL takes it correctly. This is all I need. And ,as ShaunR mentioned, "the C pointer (asterisk) makes me tentative, however, since it could be a ByRef". So I need to verify this as well.

Link to comment

Unfortunately, nothing I have tried works.

This is how the header file looks like:

 

#include "extcode.h"
#pragma pack(push)
#pragma pack(1)

#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
 LVBoolean status;
 int32_t code;
 LStrHandle source;
 } TD1;


void __cdecl LCDColor(LVRefNum *VISAIN, uint16_t LCDColor2, TD1 *errorInNoError, LVRefNum *VISAOUT, char OutputString[], TD1 *errorOut, int32_t len);

 

long __cdecl LVDLLStatus(char *errStr, int errStrLen, void *module);

#ifdef __cplusplus
} // extern "C"
#endif

#pragma pack(pop)

 

Also ffrom this DLL developer I learned that inside Labview code it uses name "COM1" as a string for the Com Port under VISAIN and VISAOUT parameter, also that parameters errorIn,OutputStr, errorOut, len are optional.

 I have tried several ways to declare  and call it in VB.NET:

1.

DeclareAutoFunction LCDColor Lib"..LabVIEWdllsLCD Color.dll" (ByVal ComPortIn AsString, ByVal color As Int16, ByRef errIn As Int32, ByVal ComPortOut AsString, ByRef outPutStr AsString, ByRef errOut As Int32, ByRef len As Int32) AsInt32

 

Call  as

LCDColor("COM1", color, errorIn,"COM1", OutputStr, errorOut, len)

 

2.

DeclareAutoFunction LCDColor Lib"..LabVIEWdllsLCD Color.dll" (ByVal ComPortIn As Int32, ByVal color As Int16, ByRef errIn As Int32, ByVal ComPortOut As Int32, ByRef outPutStr AsString, ByRef errOut As Int32, ByRef len As Int32) As Int32

call as

LCDColor(1, color, errorIn, 1, OutputStr, errorOut, len)

 

3.DeclareAutoFunction LCDColor Lib"..LabVIEWdllsLCD Color.dll" (ByVal ComPortIn As IntPtr, ByVal color As Int16, ByRef errIn As Int32, ByVal ComPortOut As IntPtr, ByRef outPutStr AsString, ByRef errOut As Int32, ByRef len As Int32) As Int32

call as

Dim ComPort AsString = "COM3"

Dim ptrCom As IntPtr = Marshal.StringToHGlobalAnsi(ComPort)

LCDColor(ptrCom, color, errorIn, ptrCom, OutputStr, errorOut, len)

 

In all cases I get the same error: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

I need to have it done.

 

Thanks for any suggestions.

Link to comment

None of those declarations are correct, and the errorIn and errorOut parameters are probably not optional - they're passed by reference and should be allocated properly. Passing a pointer to an incompatible data type will likely lead to problems. It will be difficult to get the errorIn and errorOut declarations correct in VisualBasic, though, because it would involve calling functions in the LabVIEW library to allocate an LStr and then creating a handle to it. ALL of the parameters, except color and len, are by reference (that's what the asterisk in front of them in the function prototype indicates). Further, as everyone else has explained, the ComPort parameter is a reference to a VISA session that is already open (specifically it's a pointer to an integer, where that integer value has meaning only as a reference to a particular session). Passing a constant that corresponds to the COM port you want to open WILL NOT WORK. You cannot call this function successfully without a prior call to open the session. If that function does not exist in the DLL, then you need to ask the DLL creator to add it for you. At the same time they should remove the errorIn and errorOut parameters, or at the least replace them with a data type that is more compatible with VisualBasic.

  • Like 1
Link to comment

Thanks a lot for the detailed explanation. I thought that calling Labiew DLL with VISA parameters was quite popular and expected to find clear examples. Unfortunately few examples NI provides show passing regular but not LabVIEW specific variables.

Link to comment

Since "ComPort parameter is a reference to a VISA session ... and passing a constant that corresponds to the COM port you want to open WILL NOT WORK" could it be done different way? For example, currently I have a parameter  COLOR passing as simple integer which LV DLL uses inside its own way to change LCD color. Now could be similar approach used for VISA parameter or that cluster ERROR variables? For example, instead passing real VISA type parameter, VB sends an integer 1, and and a code inside DLL just makes a selection such as  if this number =1 then use  COM1, if this number =2 then use  COM2. In this case VB would deal with its own standard variables and Labiew would deal with its own data types.

Link to comment

You wrote earlier:

I don't create this DLL, I don't program Labview. I only get a header file from Labiew project with calling parameters knowing that this is a variable for a Com Port.

Do you have the ability to change the DLL? If so, then there are several ways to make it work. If not, then you're out of luck.

Link to comment

Yes. The DLL I posted was a debugging example. Real Labview DLLs will be developed by LabView programmer to be called from my VB.net application. DLLs can changed to accomodate any calling needs. Since I am not Labview developer I need to find a way to call that DLLs and explain LV programmer my requirements as long as they are duable in Labview.  

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.