Page 1 of 1

Calling DLL Functions (Interfacing with LabJack Drivers)

Posted: Mon Jul 31, 2006 8:06 pm
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

Posted: Mon Jul 31, 2006 8:25 pm
by Xombie
Should you be passing the address of the string rather than just "1" ?

Posted: Mon Jul 31, 2006 8:52 pm
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.

Posted: Mon Jul 31, 2006 9:41 pm
by KarLKoX
Prototype.l ProtoOpenLabJack(DeviceType.l, ConnectionType.l, Address.l, FirstFound.l, *pHandle.l)

errorcode.l = fOpenLabJack( 9, 1, @"1", 1, *pHandle)

Posted: Mon Jul 31, 2006 11:17 pm
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

Posted: Tue Aug 01, 2006 12:02 am
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.

Posted: Tue Aug 01, 2006 12:26 am
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.

Posted: Tue Aug 01, 2006 12:42 am
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

Posted: Tue Aug 01, 2006 6:32 am
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