Calling DLL Functions (Interfacing with LabJack Drivers)

Just starting out? Need help? Post your questions and find answers here.
stenslat
New User
New User
Posts: 5
Joined: Mon Jul 31, 2006 7:38 pm

Calling DLL Functions (Interfacing with LabJack Drivers)

Post by stenslat »

I am trying to call some driver functions for a LabJack UE9 USB/Ethernet data acquisition device. So far I have been successful with the simple GetDriverVersion function, but when I try to call OpenLabJack I get "[ERROR] Invalid memory address". Probably something wrong with the string parameter or the handle pointer.



Here are the C-prototypes for the 2 functions I am trying to call so far:

double _stdcall GetDriverVersion(void);

LJ_ERROR _stdcall OpenLabJack(long DeviceType, long ConnectionType, const char *pAddress, long FirstFound, LJ_HANDLE *pHandle);



Here is my PureBasic code:

OpenConsole()
ConsoleTitle ("LabJackUD PureBasic Example:")
EnableGraphicalConsole(0)

Prototype.d ProtoGetDriverVersion()
Prototype.l ProtoOpenLabJack(DeviceType.l, ConnectionType.l, Address$, FirstFound.l, *pHandle.l)

If OpenLibrary(0,"labjackud.dll")

fGetDriverVersion.ProtoGetDriverVersion = GetFunction(0, "GetDriverVersion")
driverVersion.d = fGetDriverVersion()
PrintN(StrD(driverVersion.d))

fOpenLabJack.ProtoOpenLabJack = GetFunction(0, "OpenLabJack")
errorcode.l = fOpenLabJack( 9, 1, "1", 1, *pHandle)

Else
PrintN("Open Library Failed")
EndIf

Print ("Press <Enter> to exit: ")
name$=Input()

CloseLibrary(0)
CloseConsole()
End
Xombie
Addict
Addict
Posts: 898
Joined: Thu Jul 01, 2004 2:51 am
Location: Tacoma, WA
Contact:

Post by Xombie »

Should you be passing the address of the string rather than just "1" ?
stenslat
New User
New User
Posts: 5
Joined: Mon Jul 31, 2006 7:38 pm

Post by stenslat »

I don't know as I don't have a very good understanding of pointers in PureBasic. In VB, the function is declared as:

Declare Function OpenLabJack Lib "labjackud.dll" (ByVal DeviceType As Long, ByVal ConnectionType As Long, ByVal pAddress As String, ByVal FirstFound As Long, ByRef pHandle As Long) As Long

... and simply called as:

lngError = OpenLabJack(LJ_dtUE9, LJ_ctUSB, "1", 1, lngHandle)


Note that since the Address in the driver is defined as a "const char *" it is passed ByVal in VB. If it was a "char *" then it would be ByRef in VB.
KarLKoX
Enthusiast
Enthusiast
Posts: 681
Joined: Mon Oct 06, 2003 7:13 pm
Location: France
Contact:

Post by KarLKoX »

Prototype.l ProtoOpenLabJack(DeviceType.l, ConnectionType.l, Address.l, FirstFound.l, *pHandle.l)

errorcode.l = fOpenLabJack( 9, 1, @"1", 1, *pHandle)
"Qui baise trop bouffe un poil." P. Desproges

http://karlkox.blogspot.com/
stenslat
New User
New User
Posts: 5
Joined: Mon Jul 31, 2006 7:38 pm

Post by stenslat »

Same error. The revised code is below. If anyone wants to try it themselves run the UD installer from the U3 or UE9 downloads page at labjack.com. This puts labjackud.dll in the system directory and puts the header file in the install directory. The OpenLabJack function should return errorcode=1007 with no hardware connected.


OpenConsole()
ConsoleTitle ("LabJackUD PureBasic Example:")
EnableGraphicalConsole(0)

Prototype.d ProtoGetDriverVersion()
Prototype.l ProtoOpenLabJack(DeviceType.l, ConnectionType.l, Address.l, FirstFound.l, *pHandle.l)

If OpenLibrary(0,"labjackud.dll")

fGetDriverVersion.ProtoGetDriverVersion = GetFunction(0, "GetDriverVersion")
driverVersion.d = fGetDriverVersion()
PrintN(StrD(driverVersion.d))

fOpenLabJack.ProtoOpenLabJack = GetFunction(0, "OpenLabJack")
errorcode.l = fOpenLabJack( 9, 1, @"1", 1, *pHandle)

Else
PrintN("Open Library Failed")
EndIf

Print ("Press <Enter> to exit: ")
name$=Input()

CloseLibrary(0)
CloseConsole()
End
Xombie
Addict
Addict
Posts: 898
Joined: Thu Jul 01, 2004 2:51 am
Location: Tacoma, WA
Contact:

Post by Xombie »

I can't actually download and try out the labjack software at the moment but I read through their documentation. It seems *pAddress should be the local ID of the USB device? Unless you're using Ethernet and then it's the IP Address. For ethernet, I'm betting on passing a pointer to the string containing the IP address. For USB, I think you need to get the local id for the device. I see ListAll() will return an array of the local ids in *pID that you could then pass to OpenLabJack().

Does any of that make sense? I only browsed the documentation for a few minutes.
stenslat
New User
New User
Posts: 5
Joined: Mon Jul 31, 2006 7:38 pm

Post by stenslat »

I am actually an engineer at LabJack. We are trying to make a PureBasic example in response to a customer request. You are correct that Address is an IP address for Ethernet and a LocalID for USB. If using Ethernet you pass the IP address as a string ("192.168.1.209"), if using USB you pass the LocalID (which is 1 for my test UE9) as a string, or if you set FirstFound to TRUE the LocalID is ignored and the driver simply uses the first USB UE9 that it finds.
jack
Addict
Addict
Posts: 1358
Joined: Fri Apr 25, 2003 11:10 pm

Post by jack »

Code: Select all

OpenConsole() 
ConsoleTitle ("LabJackUD PureBasic Example:") 
EnableGraphicalConsole(0) 
pHandle.l
Prototype.d ProtoGetDriverVersion() 
Prototype.l ProtoOpenLabJack(DeviceType.l, ConnectionType.l, Address.s, FirstFound.l, *pHandle.l) 

If OpenLibrary(0,"labjackud.dll") 

  fGetDriverVersion.ProtoGetDriverVersion = GetFunction(0, "GetDriverVersion") 
  driverVersion.d = fGetDriverVersion() 
  PrintN(StrD(driverVersion.d)) 

  fOpenLabJack.ProtoOpenLabJack = GetFunction(0, "OpenLabJack") 
  errorcode.l = fOpenLabJack( 9, 1, "1", 1, @pHandle) 
  PrintN("Error code = "+Str(errorcode))
Else 
  PrintN("Open Library Failed") 
EndIf 

Print ("Press <Enter> to exit: ") 
name$=Input() 

CloseLibrary(0) 
CloseConsole() 
End
or you could use the import lib and do the following.

Code: Select all

OpenConsole() 
ConsoleTitle ("LabJackUD PureBasic Example:") 
EnableGraphicalConsole(0) 
pHandle.l

Import "labjackud.lib"
  OpenLabJack.l(DeviceType.l, ConnectionType.l, pAddress.s, FirstFound.l, *pHandle.l) As "_OpenLabJack@20"
  GetDriverVersion.d() As "_GetDriverVersion@0"
EndImport
driverVersion.d = GetDriverVersion()
PrintN(StrD(driverVersion))
errorcode.l = OpenLabJack( 9, 1, "1", 1, @pHandle) 
PrintN("Error code = "+Str(errorcode))
Print ("Press <Enter> to exit: ") 
name$=Input() 

CloseConsole() 
End
stenslat
New User
New User
Posts: 5
Joined: Mon Jul 31, 2006 7:38 pm

Post by stenslat »

That did the trick. Thanks. Following is the code we now have for a simple example to communicate with the LabJack UE9 with PureBasic:


;
;Simple PureBasic example for the LabJack UE9.
;support@labjack.com
;Jul 31, 2006
;

OpenConsole()
ConsoleTitle ("LabJackUD PureBasic Example:")
EnableGraphicalConsole(0)

lngErrorcode.l
lngHandle.l
dblValue.d
Prototype.d ProtoGetDriverVersion()
Prototype.l ProtoOpenLabJack(DeviceType.l, ConnectionType.l, Address.s, FirstFound.l, *lngHandle.l)
Prototype.l ProtoeGetS(pHandle.l, IOType.s, Channel.l, *dblValue.d, x1.l)
Prototype.l ProtoeGetSS(pHandle.l, IOType.s, Channel.s, *dblValue.d, x1.l)
;The former is used with most basic IOTypes that operate on a particular
;channel, while the latter is generally used with the put_config/get_config
;types operating on the device as a whole.

If OpenLibrary(0,"labjackud.dll")

fGetDriverVersion.ProtoGetDriverVersion = GetFunction(0, "GetDriverVersion")
fOpenLabJack.ProtoOpenLabJack = GetFunction(0, "OpenLabJack")
feGetS.ProtoeGetS = GetFunction(0, "eGetS")
feGetSS.ProtoeGetSS = GetFunction(0, "eGetSS")

;Get the UD driver version.
driverVersion.d = fGetDriverVersion()
PrintN("GetDriverVersion = "+StrD(driverVersion,2))

;Open the first found USB LabJack UE9.
;DeviceType: U3=3 or UE9=9
;ConnectionType: USB=1 or Ethernet=2
lngErrorcode = fOpenLabJack( 9, 1, "1", 1, @lngHandle)
PrintN("OpenLabJack errorcode = "+Str(lngErrorcode))

;Read the serial number of the LabJack.
lngErrorcode = feGetSS( lngHandle, "LJ_ioGET_CONFIG", "LJ_chSERIAL_NUMBER", @dblValue, 0)
PrintN("")
PrintN("errorcode = "+Str(lngErrorcode))
PrintN("Serial Number = "+StrD(dblValue,0))

;Get a reading from analog input 0 (AIN0).
lngErrorcode = feGetS( lngHandle, "LJ_ioGET_AIN", 0, @dblValue, 0)
PrintN("")
PrintN("errorcode = "+Str(lngErrorcode))
PrintN("AIN0 = "+StrD(dblValue,6))

;Get a reading from digital input 0 (FIO0).
lngErrorcode = feGetS( lngHandle, "LJ_ioGET_DIGITAL_BIT", 0, @dblValue, 0)
PrintN("")
PrintN("errorcode = "+Str(lngErrorcode))
PrintN("FIO0 = "+StrD(dblValue,0))

;Set analog output 0 (DAC0) to 2.5 volts.
dblValue = 2.5
lngErrorcode = feGetS( lngHandle, "LJ_ioPUT_DAC", 0, @dblValue, 0)
PrintN("")
PrintN("errorcode = "+Str(lngErrorcode))
PrintN("DAC0 set to 2.5 volts")

;Set digital line 1 (FIO1) to output-low .
dblValue = 0
lngErrorcode = feGetS( lngHandle, "LJ_ioPUT_DIGITAL_BIT", 1, @dblValue, 0)
PrintN("")
PrintN("errorcode = "+Str(lngErrorcode))
PrintN("FIO1 set to output-low")


Else
PrintN("Open Library Failed")
EndIf

PrintN("")
Print ("Press <Enter> to exit: ")
name$=Input()

CloseLibrary(0)
CloseConsole()
End
Post Reply