Alex723 Posted June 17, 2013 Report Share Posted June 17, 2013 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. Quote Link to comment
ShaunR Posted June 17, 2013 Report Share Posted June 17, 2013 (edited) 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 June 17, 2013 by ShaunR Quote Link to comment
Alex723 Posted June 18, 2013 Author Report Share Posted June 18, 2013 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. Quote Link to comment
Aristos Queue Posted June 18, 2013 Report Share Posted June 18, 2013 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. Quote Link to comment
ShaunR Posted June 18, 2013 Report Share Posted June 18, 2013 (edited) 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 June 18, 2013 by ShaunR Quote Link to comment
Alex723 Posted June 18, 2013 Author Report Share Posted June 18, 2013 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. Quote Link to comment
Alex723 Posted June 20, 2013 Author Report Share Posted June 20, 2013 Unfortunately, nothing I have tried works. This is how the header file looks like: #include "extcode.h"#pragma pack(push)#pragma pack(1) #ifdef __cplusplusextern "C" {#endiftypedef 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. Quote Link to comment
ned Posted June 20, 2013 Report Share Posted June 20, 2013 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. 1 Quote Link to comment
Alex723 Posted June 20, 2013 Author Report Share Posted June 20, 2013 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. Quote Link to comment
Alex723 Posted June 21, 2013 Author Report Share Posted June 21, 2013 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. Quote Link to comment
ShaunR Posted June 21, 2013 Report Share Posted June 21, 2013 You need to call an initialising function first and it will return the reference that you can then pass to your other functions. Quote Link to comment
ned Posted June 21, 2013 Report Share Posted June 21, 2013 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. Quote Link to comment
Alex723 Posted June 21, 2013 Author Report Share Posted June 21, 2013 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. Quote Link to comment
Rolf Kalbermatter Posted June 21, 2013 Report Share Posted June 21, 2013 Attachment to post on the NI site, as the attachment upload seems borked there. VB VISA.zip Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.