' USB LISM-PI26xx VB.NET wrapper for Windows
' Library version 2.x - legacy API and handle-based *_ex API
'
' Compatible with existing VB.NET examples that use the global
' UsbLismPi26 class and call UsbLismPi26.Load().
' Uses LoadLibrary/GetProcAddress and therefore does not require
' System.Runtime.InteropServices.NativeLibrary.
'
' Supported managed targets: .NET Framework and modern .NET on Windows.
' The process architecture selects usblismpi2632.dll or usblismpi2664.dll.

Option Strict On
Option Explicit On
Option Infer On

Imports System
Imports System.IO
Imports System.Reflection
Imports System.Runtime.InteropServices
Imports System.Security

Public NotInheritable Class UsbLismPi26
    Private Sub New()
    End Sub

#Region "Native loader"
    <SuppressUnmanagedCodeSecurity()>
    Private NotInheritable Class Win32
        Private Sub New()
        End Sub

        <DllImport("kernel32.dll", EntryPoint:="LoadLibraryW", CharSet:=CharSet.Unicode, SetLastError:=True)>
        Friend Shared Function LoadLibrary(fileName As String) As IntPtr
        End Function

        <DllImport("kernel32.dll", EntryPoint:="GetProcAddress", CharSet:=CharSet.Ansi, SetLastError:=True, ExactSpelling:=True)>
        Friend Shared Function GetProcAddress(moduleHandle As IntPtr, procedureName As String) As IntPtr
        End Function

        <DllImport("kernel32.dll", EntryPoint:="FreeLibrary", SetLastError:=True, ExactSpelling:=True)>
        Friend Shared Function FreeLibrary(moduleHandle As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
        End Function
    End Class

    Private Shared ReadOnly LoaderSync As New Object()
    Private Shared libraryHandle As IntPtr = IntPtr.Zero
    Private Shared loadedLibraryPathValue As String = Nothing

    Public Shared ReadOnly Property DefaultDllName As String
        Get
            Return If(Environment.Is64BitProcess, "usblismpi2664.dll", "usblismpi2632.dll")
        End Get
    End Property

    Public Shared ReadOnly Property IsLoaded As Boolean
        Get
            SyncLock LoaderSync
                Return libraryHandle <> IntPtr.Zero
            End SyncLock
        End Get
    End Property

    Public Shared ReadOnly Property LoadedLibraryPath As String
        Get
            SyncLock LoaderSync
                Return loadedLibraryPathValue
            End SyncLock
        End Get
    End Property

    Private Shared Function ResolveLibraryPath(dllPath As String) As String
        Dim requested As String = If(String.IsNullOrWhiteSpace(dllPath), DefaultDllName, dllPath.Trim())

        If Path.IsPathRooted(requested) Then
            Return requested
        End If

        Dim candidates As String() = {
            Path.Combine(AppDomain.CurrentDomain.BaseDirectory, requested),
            Path.Combine(Environment.CurrentDirectory, requested)
        }

        For Each candidate As String In candidates
            If File.Exists(candidate) Then
                Return Path.GetFullPath(candidate)
            End If
        Next

        ' Let Windows perform its standard DLL search as a final fallback.
        Return requested
    End Function

    Private Shared Function Bind(symbol As String, delegateType As Type) As [Delegate]
        Dim address As IntPtr = Win32.GetProcAddress(libraryHandle, symbol)
        If address = IntPtr.Zero Then
            Dim errorCode As Integer = Marshal.GetLastWin32Error()
            Throw New EntryPointNotFoundException(
                String.Format("Export '{0}' was not found in '{1}' (Win32 error {2}).", symbol, loadedLibraryPathValue, errorCode))
        End If
        Return Marshal.GetDelegateForFunctionPointer(address, delegateType)
    End Function

    Private Shared Sub BindAllExports()
        Dim flags As BindingFlags = BindingFlags.Public Or BindingFlags.Static
        For Each field As FieldInfo In GetType(UsbLismPi26).GetFields(flags)
            If GetType([Delegate]).IsAssignableFrom(field.FieldType) Then
                field.SetValue(Nothing, Bind(field.Name, field.FieldType))
            End If
        Next
    End Sub

    Private Shared Sub ClearAllDelegates()
        Dim flags As BindingFlags = BindingFlags.Public Or BindingFlags.Static
        For Each field As FieldInfo In GetType(UsbLismPi26).GetFields(flags)
            If GetType([Delegate]).IsAssignableFrom(field.FieldType) Then
                field.SetValue(Nothing, Nothing)
            End If
        Next
    End Sub

    ''' <summary>Loads the matching 32-bit or 64-bit DLL and resolves all public exports.</summary>
    ''' <param name="dllPath">Optional absolute or relative DLL path. Omit to use the process-bitness default.</param>
    ''' <returns>RET_OK on success; otherwise the Win32 LoadLibrary error code.</returns>
    Public Shared Function Load(Optional dllPath As String = Nothing) As UInteger
        SyncLock LoaderSync
            If libraryHandle <> IntPtr.Zero Then
                Return RET_OK
            End If

            If Environment.OSVersion.Platform <> PlatformID.Win32NT Then
                Throw New PlatformNotSupportedException("This compatibility wrapper supports Windows only.")
            End If

            Dim resolvedPath As String = ResolveLibraryPath(dllPath)
            libraryHandle = Win32.LoadLibrary(resolvedPath)
            If libraryHandle = IntPtr.Zero Then
                Return CUInt(Marshal.GetLastWin32Error())
            End If

            loadedLibraryPathValue = resolvedPath
            Try
                BindAllExports()
                Return RET_OK
            Catch
                ClearAllDelegates()
                Win32.FreeLibrary(libraryHandle)
                libraryHandle = IntPtr.Zero
                loadedLibraryPathValue = Nothing
                Throw
            End Try
        End SyncLock
    End Function

    ''' <summary>Unloads the DLL. Close all legacy and *_ex devices before calling this method.</summary>
    Public Shared Sub Free()
        SyncLock LoaderSync
            ClearAllDelegates()
            If libraryHandle <> IntPtr.Zero Then
                Win32.FreeLibrary(libraryHandle)
                libraryHandle = IntPtr.Zero
            End If
            loadedLibraryPathValue = Nothing
        End SyncLock
    End Sub
#End Region

#Region "Constants"
    Public Const RET_OK As UInteger = 0UI
    Public Const LS_OK As UInteger = 0UI
    Public Const LS_ERR_NO_DEVICES_ATTACHED As UInteger = &H20000001UI
    Public Const LS_ERR_DEVICE_INDEX_OUT_OF_RANGE As UInteger = &H20000002UI
    Public Const LS_ERR_SERIAL_NUM_NOT_FOUND As UInteger = &H20000003UI
    Public Const LS_ERR_INVALID_HANDLE As UInteger = 6UI
    Public Const LS_ERR_DEVICE_ACTIVE As UInteger = &H20000011UI
    Public Const LS_ERR_CONTROL_TRANSFER As UInteger = &H20000015UI
    Public Const LS_ERR_TIMEOUT As UInteger = 1460UI
    Public Const LS_ERR_DEVICE_ALREADY_OPEN As UInteger = &H20000013UI
    Public Const LS_ERR_NOT_IMPLEMENTED As UInteger = &H20000014UI
    Public Const LS_ERR_ALLOCATE_THREADPARAM_MEM As UInteger = &H20000004UI
    Public Const LS_ERR_PATH_INVALID_HANDLE As UInteger = &H20000006UI
    Public Const LS_ERR_INVALID_DATALEN As UInteger = &H21000001UI
    Public Const LS_ERR_I2C_NACK As UInteger = &H21000004UI
    Public Const LS_ERR_I2C_ERROR As UInteger = &H21000005UI
    Public Const LS_ERR_I2C_UNKNOWN As UInteger = &H21000006UI
    Public Const LS_ERR_I2C_MUX_DISABLED As UInteger = &H21000007UI
    Public Const LS_ERR_INVALID_PACKETLENGTH As UInteger = &H21000002UI
    Public Const LS_ERR_CMD_NOT_SUPPORTED As UInteger = &H21000003UI
    Public Const LS_ERR_PIPE_CANCELLED As UInteger = 109UI
    Public Const LS_ERR_INVALID_TIMEOUT As UInteger = &H21000008UI
    Public Const LS_ERR_INVALID_THREAD_PRIORITY As UInteger = &H21000009UI
    Public Const LS_ERR_THREAD_PRIORITY_FAILED As UInteger = &H2100000AUI

    ' Common Win32 aliases retained for legacy source compatibility.
    Public Const ERROR_INVALID_HANDLE As UInteger = 6UI
    Public Const ERROR_BROKEN_PIPE As UInteger = 109UI
    Public Const ERROR_TIMEOUT As UInteger = 1460UI
    Public Const INFINITE As UInteger = &HFFFFFFFFUI

    Public Const DEFAULT_TIMEOUT_MS As UInteger = 1000UI
    Public Const LS_THREAD_PRIORITY_NORMAL As Integer = 0
    Public Const LS_THREAD_PRIORITY_ABOVE_NORMAL As Integer = 1
    Public Const LS_THREAD_PRIORITY_HIGH As Integer = 2

    Public Const _512 As UInteger = 512UI
    Public Const _1kB As UInteger = _512 * 2UI
    Public Const _2kB As UInteger = _1kB * 2UI
    Public Const _4kB As UInteger = _2kB * 2UI
    Public Const _8kB As UInteger = _4kB * 2UI
    Public Const _16kB As UInteger = _8kB * 2UI
    Public Const _32kB As UInteger = _16kB * 2UI
    Public Const _64kB As UInteger = _32kB * 2UI
    Public Const _128kB As UInteger = _64kB * 2UI
    Public Const _256kB As UInteger = _128kB * 2UI
    Public Const _512kB As UInteger = _256kB * 2UI
    Public Const _1MB As UInteger = _512kB * 2UI
    Public Const _2MB As UInteger = _1MB * 2UI
    Public Const _4MB As UInteger = _2MB * 2UI
    Public Const _8MB As UInteger = _4MB * 2UI
    Public Const _16MB As UInteger = _8MB * 2UI
    Public Const _32MB As UInteger = _16MB * 2UI
    Public Const _64MB As UInteger = _32MB * 2UI
    Public Const _128MB As UInteger = _64MB * 2UI
    Public Const _256MB As UInteger = _128MB * 2UI

    Public Const _1ms As UInteger = 1UI
    Public Const _1s As UInteger = 1000UI * _1ms
    Public Const LISM_ADDR As Byte = &HFE

    Public Const MODE_FREE_RUNNING As Byte = &H00
    Public Const MODE_EXT_RISING_EDGE_SL As Byte = &H01
    Public Const MODE_EXT_HIGH_LEVEL As Byte = &H02
    Public Const MODE_INT_SOFT_TRIGGER As Byte = &H03
    Public Const MODE_QUAD_ENC_TRIGGER As Byte = &H04
    Public Const MODE_EXT_RISING_EDGE_ML As Byte = &H05
    Public Const MODE_ENCODER_DIR_CW As Byte = &H00
    Public Const MODE_ENCODER_DIR_CCW As Byte = &H10
    Public Const MODE_ENCODER_CNT_DISABLE As Byte = &H00
    Public Const MODE_ENCODER_CNT_ENABLE As Byte = &H20
    Public Const IF_DCLK_400KHZ As Byte = &H00
    Public Const IF_DCLK_500KHZ As Byte = &H01
    Public Const IF_DCLK_800KHZ As Byte = &H02
    Public Const IF_DCLK_1MHZ As Byte = &H03
    Public Const IF_DCLK_2MHZ As Byte = &H04
    Public Const IF_DCLK_4MHZ As Byte = &H05
    Public Const IF_DCLK_10MHZ As Byte = &H06
    Public Const IF_DCLK_20MHZ As Byte = &H07
    Public Const IF_DCLK_POL_RISING_EDGE As Byte = &H00
    Public Const IF_DCLK_POL_FALLING_EDGE As Byte = &H08
    Public Const IF_LINE_VALID_HIGH As Byte = &H00
    Public Const IF_LINE_VALID_LOW As Byte = &H10
    Public Const IF_FRAME_VALID_HIGH As Byte = &H00
    Public Const IF_FRAME_VALID_LOW As Byte = &H20
    Public Const IF_TRIGGER_OUTPUT_HIGH As Byte = &H00
    Public Const IF_TRIGGER_OUTPUT_LOW As Byte = &H40
    Public Const ADC_VREF_1V6 As Byte = &H00
    Public Const ADC_VREF_2V0 As Byte = &H01
#End Region

#Region "Delegate types"
    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_libversion() As UShort

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_initialize(pipe_size As UInteger, _
                                      packet_length As UInteger, _
                                      thread_class As UInteger, _
                                      thread_priority As Integer, _
                                      <MarshalAs(UnmanagedType.LPStr)> message_id As String) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_enumdevices() As Integer

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getfwversion(index As Integer) As UShort

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getvendorname(index As Integer) As IntPtr

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getproductname(index As Integer) As IntPtr

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getserialnumber(index As Integer) As IntPtr

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_devicecount() As Byte

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_currentdeviceindex() As Integer

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_opendevicebyindex(index As Integer) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_opendevicebyserial(<MarshalAs(UnmanagedType.LPStr)> serial_num As String) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_closedevice() As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_waitforpipe(timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_waitforpipecount(count As Integer, _
                                      ByRef available As Integer, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getpipe(buffer As IntPtr, _
                                      to_read As UInteger, _
                                      ByRef read_count As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setpacketlength(packet_length As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_seteptimeout(timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_geteptimeout() As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getfps() As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_geterrorstring(error_code As UInteger) As IntPtr

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_customfirmware(ByRef custom_firmware As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setcfg1(cfg1 As Byte) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getcfg1(ByRef cfg1 As Byte) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getpacketlength(ByRef packet_length As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setmuxchannel(mux As Byte) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getmuxchannel(ByRef mux As SByte) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_readi2c_ext(i2c_address As Byte, _
                                      buffer As IntPtr, _
                                      ByRef length As UShort) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_writei2c_ext(i2c_address As Byte, _
                                      buffer As IntPtr, _
                                      length As UShort) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_readi2c(i2c_address As Byte, _
                                      buffer As IntPtr, _
                                      ByRef length As UShort) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_writei2c(i2c_address As Byte, _
                                      buffer As IntPtr, _
                                      length As UShort) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_i2cread1byte(i2c_address As Byte, _
                                      i2c_register As Byte, _
                                      ByRef value As Byte) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_i2cread2bytes(i2c_address As Byte, _
                                      i2c_register As Byte, _
                                      ByRef value As UShort) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_i2cread4bytes(i2c_address As Byte, _
                                      i2c_register As Byte, _
                                      ByRef value As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_i2cwrite1byte(i2c_address As Byte, _
                                      i2c_register As Byte, _
                                      value As Byte) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_i2cwrite2bytes(i2c_address As Byte, _
                                      i2c_register As Byte, _
                                      value As UShort) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_i2cwrite4bytes(i2c_address As Byte, _
                                      i2c_register As Byte, _
                                      value As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_i2cwritecmd(i2c_address As Byte, _
                                      i2c_command As Byte) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_hw_reset(address As Byte) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_suspend(address As Byte) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_resume(address As Byte) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_updateparam(address As Byte) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setstate(address As Byte, _
                                      state As Byte) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setmodeconfig(address As Byte, _
                                      mode As Byte) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setifconfig(address As Byte, _
                                      config As Byte) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setstpulse(address As Byte, _
                                      high_value As UInteger, _
                                      low_value As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setsthigh(address As Byte, _
                                      high_value As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setstlow(address As Byte, _
                                      low_value As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setlinesperframe(address As Byte, _
                                      lines As UShort) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setquadcount(address As Byte, _
                                      count As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setsofttriggertime(address As Byte, _
                                      time_value As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_settriggerdelay(address As Byte, _
                                      delay_value As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_settriggerwidth(address As Byte, _
                                      width_value As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setpixelcount(address As Byte, _
                                      pixel_count As UShort) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setedgedelay(address As Byte, _
                                      edge_delay As Byte) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setadcvref(address As Byte, _
                                      vref As Byte) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setadcgain(address As Byte, _
                                      gain As Byte) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setadcoffset(address As Byte, _
                                      offset As UShort) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setadcbias(address As Byte, _
                                      bias As UShort) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setslaveaddress(address As Byte, _
                                      new_address As Byte) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_saveslaveaddress(address As Byte) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_savesettings(address As Byte) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_reloadsettings(address As Byte) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_resetsettings(address As Byte) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getmcuversion(address As Byte, _
                                      ByRef version As UShort) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getctgversion(address As Byte, _
                                      ByRef version As UShort) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getctgstate(address As Byte, _
                                      ByRef state As Byte) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getstate(address As Byte, _
                                      ByRef state As Byte) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getmodeconfig(address As Byte, _
                                      ByRef mode As Byte) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getifconfig(address As Byte, _
                                      ByRef config As Byte) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getstpulse(address As Byte, _
                                      ByRef high_value As UInteger, _
                                      ByRef low_value As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getsthigh(address As Byte, _
                                      ByRef high_value As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getstlow(address As Byte, _
                                      ByRef low_value As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getlinesperframe(address As Byte, _
                                      ByRef lines As UShort) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getquadcount(address As Byte, _
                                      ByRef count As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getsofttriggertime(address As Byte, _
                                      ByRef time_value As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_gettriggerdelay(address As Byte, _
                                      ByRef delay_value As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_gettriggerwidth(address As Byte, _
                                      ByRef width_value As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getpixelcount(address As Byte, _
                                      ByRef pixel_count As UShort) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getedgedelay(address As Byte, _
                                      ByRef edge_delay As Byte) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getadcvref(address As Byte, _
                                      ByRef vref As Byte) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getadcgain(address As Byte, _
                                      ByRef gain As Byte) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getadcoffset(address As Byte, _
                                      ByRef offset As UShort) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getadcbias(address As Byte, _
                                      ByRef bias As UShort) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getslaveaddress(address As Byte, _
                                      ByRef new_address As Byte) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_gethw1id(address As Byte, _
                                      ByRef hardware_id As UShort) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_gethw1version(address As Byte, _
                                      ByRef version As UShort) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_gethw2version(address As Byte, _
                                      ByRef version As UShort) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getgainmult(address As Byte, _
                                      ByRef multiplier As UShort) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getgaindiv(address As Byte, _
                                      ByRef divisor As UShort) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getinitstatus(address As Byte, _
                                      ByRef status As Byte) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getcomresult(address As Byte, _
                                      ByRef result_value As Byte) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_shutdown() As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_seteptimeout_ex(handle As IntPtr, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_geteptimeout_ex(handle As IntPtr, _
                                      ByRef timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setthreadpriority_ex(handle As IntPtr, _
                                      priority As Integer) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getthreadpriority_ex(handle As IntPtr, _
                                      ByRef priority As Integer) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_opendevicebyindex_ex(index As Integer, _
                                      pipe_size As UInteger, _
                                      packet_length As UInteger, _
                                      ByRef handle As IntPtr) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_opendevicebyserial_ex(<MarshalAs(UnmanagedType.LPStr)> serial_num As String, _
                                      pipe_size As UInteger, _
                                      packet_length As UInteger, _
                                      ByRef handle As IntPtr) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_closedevice_ex(handle As IntPtr) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getpipe_ex(handle As IntPtr, _
                                      buffer As IntPtr, _
                                      to_read As UInteger, _
                                      ByRef read_count As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_waitforpipe_ex(handle As IntPtr, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_waitforpipecount_ex(handle As IntPtr, _
                                      count As Integer, _
                                      ByRef available As Integer, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getfps_ex(handle As IntPtr) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getpacketlength_ex(handle As IntPtr, _
                                      ByRef packet_length As UInteger, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_customfirmware_ex(handle As IntPtr, _
                                      ByRef custom_firmware As UInteger, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setcfg1_ex(handle As IntPtr, _
                                      cfg1 As Byte, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getcfg1_ex(handle As IntPtr, _
                                      ByRef cfg1 As Byte, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setslaveaddress_ex(handle As IntPtr, _
                                      address As Byte, _
                                      new_address As Byte, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getslaveaddress_ex(handle As IntPtr, _
                                      address As Byte, _
                                      ByRef new_address As Byte, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_saveslaveaddress_ex(handle As IntPtr, _
                                      address As Byte, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setmuxchannel_ex(handle As IntPtr, _
                                      mux As Byte, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getmuxchannel_ex(handle As IntPtr, _
                                      ByRef mux As SByte, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_readi2c_ex(handle As IntPtr, _
                                      i2c_address As Byte, _
                                      buffer As IntPtr, _
                                      ByRef length As UShort, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_writei2c_ex(handle As IntPtr, _
                                      i2c_address As Byte, _
                                      buffer As IntPtr, _
                                      length As UShort, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_readi2c_ext_ex(handle As IntPtr, _
                                      i2c_address As Byte, _
                                      buffer As IntPtr, _
                                      ByRef length As UShort, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_writei2c_ext_ex(handle As IntPtr, _
                                      i2c_address As Byte, _
                                      buffer As IntPtr, _
                                      length As UShort, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_i2cread1byte_ex(handle As IntPtr, _
                                      i2c_address As Byte, _
                                      i2c_register As Byte, _
                                      ByRef value As Byte, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_i2cread2bytes_ex(handle As IntPtr, _
                                      i2c_address As Byte, _
                                      i2c_register As Byte, _
                                      ByRef value As UShort, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_i2cread4bytes_ex(handle As IntPtr, _
                                      i2c_address As Byte, _
                                      i2c_register As Byte, _
                                      ByRef value As UInteger, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_i2cwrite1byte_ex(handle As IntPtr, _
                                      i2c_address As Byte, _
                                      i2c_register As Byte, _
                                      value As Byte, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_i2cwrite2bytes_ex(handle As IntPtr, _
                                      i2c_address As Byte, _
                                      i2c_register As Byte, _
                                      value As UShort, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_i2cwrite4bytes_ex(handle As IntPtr, _
                                      i2c_address As Byte, _
                                      i2c_register As Byte, _
                                      value As UInteger, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_i2cwritecmd_ex(handle As IntPtr, _
                                      i2c_address As Byte, _
                                      i2c_command As Byte, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_hw_reset_ex(handle As IntPtr, _
                                      address As Byte, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_resume_ex(handle As IntPtr, _
                                      address As Byte, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_suspend_ex(handle As IntPtr, _
                                      address As Byte, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_updateparam_ex(handle As IntPtr, _
                                      address As Byte, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setstate_ex(handle As IntPtr, _
                                      address As Byte, _
                                      state As Byte, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setmodeconfig_ex(handle As IntPtr, _
                                      address As Byte, _
                                      mode As Byte, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setifconfig_ex(handle As IntPtr, _
                                      address As Byte, _
                                      config As Byte, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setsthigh_ex(handle As IntPtr, _
                                      address As Byte, _
                                      high_value As UInteger, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setstlow_ex(handle As IntPtr, _
                                      address As Byte, _
                                      low_value As UInteger, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setstpulse_ex(handle As IntPtr, _
                                      address As Byte, _
                                      high_value As UInteger, _
                                      low_value As UInteger, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setlinesperframe_ex(handle As IntPtr, _
                                      address As Byte, _
                                      lines As UShort, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setquadcount_ex(handle As IntPtr, _
                                      address As Byte, _
                                      count As UInteger, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setsofttriggertime_ex(handle As IntPtr, _
                                      address As Byte, _
                                      time_value As UInteger, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_settriggerdelay_ex(handle As IntPtr, _
                                      address As Byte, _
                                      delay_value As UInteger, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_settriggerwidth_ex(handle As IntPtr, _
                                      address As Byte, _
                                      width_value As UInteger, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setpixelcount_ex(handle As IntPtr, _
                                      address As Byte, _
                                      pixel_count As UShort, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setedgedelay_ex(handle As IntPtr, _
                                      address As Byte, _
                                      edge_delay As Byte, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setadcvref_ex(handle As IntPtr, _
                                      address As Byte, _
                                      vref As Byte, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setadcgain_ex(handle As IntPtr, _
                                      address As Byte, _
                                      gain As Byte, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setadcoffset_ex(handle As IntPtr, _
                                      address As Byte, _
                                      offset As UShort, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_setadcbias_ex(handle As IntPtr, _
                                      address As Byte, _
                                      bias As UShort, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getctgstate_ex(handle As IntPtr, _
                                      address As Byte, _
                                      ByRef state As Byte, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getstate_ex(handle As IntPtr, _
                                      address As Byte, _
                                      ByRef state As Byte, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getmodeconfig_ex(handle As IntPtr, _
                                      address As Byte, _
                                      ByRef mode As Byte, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getifconfig_ex(handle As IntPtr, _
                                      address As Byte, _
                                      ByRef config As Byte, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getsthigh_ex(handle As IntPtr, _
                                      address As Byte, _
                                      ByRef high_value As UInteger, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getstlow_ex(handle As IntPtr, _
                                      address As Byte, _
                                      ByRef low_value As UInteger, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getstpulse_ex(handle As IntPtr, _
                                      address As Byte, _
                                      ByRef high_value As UInteger, _
                                      ByRef low_value As UInteger, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getlinesperframe_ex(handle As IntPtr, _
                                      address As Byte, _
                                      ByRef lines As UShort, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getquadcount_ex(handle As IntPtr, _
                                      address As Byte, _
                                      ByRef count As UInteger, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getsofttriggertime_ex(handle As IntPtr, _
                                      address As Byte, _
                                      ByRef time_value As UInteger, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_gettriggerdelay_ex(handle As IntPtr, _
                                      address As Byte, _
                                      ByRef delay_value As UInteger, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_gettriggerwidth_ex(handle As IntPtr, _
                                      address As Byte, _
                                      ByRef width_value As UInteger, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getpixelcount_ex(handle As IntPtr, _
                                      address As Byte, _
                                      ByRef pixel_count As UShort, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getedgedelay_ex(handle As IntPtr, _
                                      address As Byte, _
                                      ByRef edge_delay As Byte, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getadcvref_ex(handle As IntPtr, _
                                      address As Byte, _
                                      ByRef vref As Byte, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getadcgain_ex(handle As IntPtr, _
                                      address As Byte, _
                                      ByRef gain As Byte, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getgainmult_ex(handle As IntPtr, _
                                      address As Byte, _
                                      ByRef multiplier As UShort, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getgaindiv_ex(handle As IntPtr, _
                                      address As Byte, _
                                      ByRef divisor As UShort, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getadcoffset_ex(handle As IntPtr, _
                                      address As Byte, _
                                      ByRef offset As UShort, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getadcbias_ex(handle As IntPtr, _
                                      address As Byte, _
                                      ByRef bias As UShort, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_savesettings_ex(handle As IntPtr, _
                                      address As Byte, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_reloadsettings_ex(handle As IntPtr, _
                                      address As Byte, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_resetsettings_ex(handle As IntPtr, _
                                      address As Byte, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getinitstatus_ex(handle As IntPtr, _
                                      address As Byte, _
                                      ByRef status As Byte, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getcomresult_ex(handle As IntPtr, _
                                      address As Byte, _
                                      ByRef result_value As Byte, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getmcuversion_ex(handle As IntPtr, _
                                      address As Byte, _
                                      ByRef version As UShort, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_getctgversion_ex(handle As IntPtr, _
                                      address As Byte, _
                                      ByRef version As UShort, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_gethw1id_ex(handle As IntPtr, _
                                      address As Byte, _
                                      ByRef hardware_id As UShort, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_gethw1version_ex(handle As IntPtr, _
                                      address As Byte, _
                                      ByRef version As UShort, _
                                      timeout_ms As UInteger) As UInteger

    <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
    Public Delegate Function T_gethw2version_ex(handle As IntPtr, _
                                      address As Byte, _
                                      ByRef version As UShort, _
                                      timeout_ms As UInteger) As UInteger

#End Region

#Region "Resolved library functions"
    Public Shared ls_libversion As T_libversion
    Public Shared ls_initialize As T_initialize
    Public Shared ls_enumdevices As T_enumdevices
    Public Shared ls_getfwversion As T_getfwversion
    Public Shared ls_getvendorname As T_getvendorname
    Public Shared ls_getproductname As T_getproductname
    Public Shared ls_getserialnumber As T_getserialnumber
    Public Shared ls_devicecount As T_devicecount
    Public Shared ls_currentdeviceindex As T_currentdeviceindex
    Public Shared ls_opendevicebyindex As T_opendevicebyindex
    Public Shared ls_opendevicebyserial As T_opendevicebyserial
    Public Shared ls_closedevice As T_closedevice
    Public Shared ls_waitforpipe As T_waitforpipe
    Public Shared ls_waitforpipecount As T_waitforpipecount
    Public Shared ls_getpipe As T_getpipe
    Public Shared ls_setpacketlength As T_setpacketlength
    Public Shared ls_seteptimeout As T_seteptimeout
    Public Shared ls_geteptimeout As T_geteptimeout
    Public Shared ls_getfps As T_getfps
    Public Shared ls_geterrorstring As T_geterrorstring
    Public Shared ls_customfirmware As T_customfirmware
    Public Shared ls_setcfg1 As T_setcfg1
    Public Shared ls_getcfg1 As T_getcfg1
    Public Shared ls_getpacketlength As T_getpacketlength
    Public Shared ls_setmuxchannel As T_setmuxchannel
    Public Shared ls_getmuxchannel As T_getmuxchannel
    Public Shared ls_readi2c_ext As T_readi2c_ext
    Public Shared ls_writei2c_ext As T_writei2c_ext
    Public Shared ls_readi2c As T_readi2c
    Public Shared ls_writei2c As T_writei2c
    Public Shared ls_i2cread1byte As T_i2cread1byte
    Public Shared ls_i2cread2bytes As T_i2cread2bytes
    Public Shared ls_i2cread4bytes As T_i2cread4bytes
    Public Shared ls_i2cwrite1byte As T_i2cwrite1byte
    Public Shared ls_i2cwrite2bytes As T_i2cwrite2bytes
    Public Shared ls_i2cwrite4bytes As T_i2cwrite4bytes
    Public Shared ls_i2cwritecmd As T_i2cwritecmd
    Public Shared ls_hw_reset As T_hw_reset
    Public Shared ls_suspend As T_suspend
    Public Shared ls_resume As T_resume
    Public Shared ls_updateparam As T_updateparam
    Public Shared ls_setstate As T_setstate
    Public Shared ls_setmodeconfig As T_setmodeconfig
    Public Shared ls_setifconfig As T_setifconfig
    Public Shared ls_setstpulse As T_setstpulse
    Public Shared ls_setsthigh As T_setsthigh
    Public Shared ls_setstlow As T_setstlow
    Public Shared ls_setlinesperframe As T_setlinesperframe
    Public Shared ls_setquadcount As T_setquadcount
    Public Shared ls_setsofttriggertime As T_setsofttriggertime
    Public Shared ls_settriggerdelay As T_settriggerdelay
    Public Shared ls_settriggerwidth As T_settriggerwidth
    Public Shared ls_setpixelcount As T_setpixelcount
    Public Shared ls_setedgedelay As T_setedgedelay
    Public Shared ls_setadcvref As T_setadcvref
    Public Shared ls_setadcgain As T_setadcgain
    Public Shared ls_setadcoffset As T_setadcoffset
    Public Shared ls_setadcbias As T_setadcbias
    Public Shared ls_setslaveaddress As T_setslaveaddress
    Public Shared ls_saveslaveaddress As T_saveslaveaddress
    Public Shared ls_savesettings As T_savesettings
    Public Shared ls_reloadsettings As T_reloadsettings
    Public Shared ls_resetsettings As T_resetsettings
    Public Shared ls_getmcuversion As T_getmcuversion
    Public Shared ls_getctgversion As T_getctgversion
    Public Shared ls_getctgstate As T_getctgstate
    Public Shared ls_getstate As T_getstate
    Public Shared ls_getmodeconfig As T_getmodeconfig
    Public Shared ls_getifconfig As T_getifconfig
    Public Shared ls_getstpulse As T_getstpulse
    Public Shared ls_getsthigh As T_getsthigh
    Public Shared ls_getstlow As T_getstlow
    Public Shared ls_getlinesperframe As T_getlinesperframe
    Public Shared ls_getquadcount As T_getquadcount
    Public Shared ls_getsofttriggertime As T_getsofttriggertime
    Public Shared ls_gettriggerdelay As T_gettriggerdelay
    Public Shared ls_gettriggerwidth As T_gettriggerwidth
    Public Shared ls_getpixelcount As T_getpixelcount
    Public Shared ls_getedgedelay As T_getedgedelay
    Public Shared ls_getadcvref As T_getadcvref
    Public Shared ls_getadcgain As T_getadcgain
    Public Shared ls_getadcoffset As T_getadcoffset
    Public Shared ls_getadcbias As T_getadcbias
    Public Shared ls_getslaveaddress As T_getslaveaddress
    Public Shared ls_gethw1id As T_gethw1id
    Public Shared ls_gethw1version As T_gethw1version
    Public Shared ls_gethw2version As T_gethw2version
    Public Shared ls_getgainmult As T_getgainmult
    Public Shared ls_getgaindiv As T_getgaindiv
    Public Shared ls_getinitstatus As T_getinitstatus
    Public Shared ls_getcomresult As T_getcomresult
    Public Shared ls_shutdown As T_shutdown
    Public Shared ls_seteptimeout_ex As T_seteptimeout_ex
    Public Shared ls_geteptimeout_ex As T_geteptimeout_ex
    Public Shared ls_setthreadpriority_ex As T_setthreadpriority_ex
    Public Shared ls_getthreadpriority_ex As T_getthreadpriority_ex
    Public Shared ls_opendevicebyindex_ex As T_opendevicebyindex_ex
    Public Shared ls_opendevicebyserial_ex As T_opendevicebyserial_ex
    Public Shared ls_closedevice_ex As T_closedevice_ex
    Public Shared ls_getpipe_ex As T_getpipe_ex
    Public Shared ls_waitforpipe_ex As T_waitforpipe_ex
    Public Shared ls_waitforpipecount_ex As T_waitforpipecount_ex
    Public Shared ls_getfps_ex As T_getfps_ex
    Public Shared ls_getpacketlength_ex As T_getpacketlength_ex
    Public Shared ls_customfirmware_ex As T_customfirmware_ex
    Public Shared ls_setcfg1_ex As T_setcfg1_ex
    Public Shared ls_getcfg1_ex As T_getcfg1_ex
    Public Shared ls_setslaveaddress_ex As T_setslaveaddress_ex
    Public Shared ls_getslaveaddress_ex As T_getslaveaddress_ex
    Public Shared ls_saveslaveaddress_ex As T_saveslaveaddress_ex
    Public Shared ls_setmuxchannel_ex As T_setmuxchannel_ex
    Public Shared ls_getmuxchannel_ex As T_getmuxchannel_ex
    Public Shared ls_readi2c_ex As T_readi2c_ex
    Public Shared ls_writei2c_ex As T_writei2c_ex
    Public Shared ls_readi2c_ext_ex As T_readi2c_ext_ex
    Public Shared ls_writei2c_ext_ex As T_writei2c_ext_ex
    Public Shared ls_i2cread1byte_ex As T_i2cread1byte_ex
    Public Shared ls_i2cread2bytes_ex As T_i2cread2bytes_ex
    Public Shared ls_i2cread4bytes_ex As T_i2cread4bytes_ex
    Public Shared ls_i2cwrite1byte_ex As T_i2cwrite1byte_ex
    Public Shared ls_i2cwrite2bytes_ex As T_i2cwrite2bytes_ex
    Public Shared ls_i2cwrite4bytes_ex As T_i2cwrite4bytes_ex
    Public Shared ls_i2cwritecmd_ex As T_i2cwritecmd_ex
    Public Shared ls_hw_reset_ex As T_hw_reset_ex
    Public Shared ls_resume_ex As T_resume_ex
    Public Shared ls_suspend_ex As T_suspend_ex
    Public Shared ls_updateparam_ex As T_updateparam_ex
    Public Shared ls_setstate_ex As T_setstate_ex
    Public Shared ls_setmodeconfig_ex As T_setmodeconfig_ex
    Public Shared ls_setifconfig_ex As T_setifconfig_ex
    Public Shared ls_setsthigh_ex As T_setsthigh_ex
    Public Shared ls_setstlow_ex As T_setstlow_ex
    Public Shared ls_setstpulse_ex As T_setstpulse_ex
    Public Shared ls_setlinesperframe_ex As T_setlinesperframe_ex
    Public Shared ls_setquadcount_ex As T_setquadcount_ex
    Public Shared ls_setsofttriggertime_ex As T_setsofttriggertime_ex
    Public Shared ls_settriggerdelay_ex As T_settriggerdelay_ex
    Public Shared ls_settriggerwidth_ex As T_settriggerwidth_ex
    Public Shared ls_setpixelcount_ex As T_setpixelcount_ex
    Public Shared ls_setedgedelay_ex As T_setedgedelay_ex
    Public Shared ls_setadcvref_ex As T_setadcvref_ex
    Public Shared ls_setadcgain_ex As T_setadcgain_ex
    Public Shared ls_setadcoffset_ex As T_setadcoffset_ex
    Public Shared ls_setadcbias_ex As T_setadcbias_ex
    Public Shared ls_getctgstate_ex As T_getctgstate_ex
    Public Shared ls_getstate_ex As T_getstate_ex
    Public Shared ls_getmodeconfig_ex As T_getmodeconfig_ex
    Public Shared ls_getifconfig_ex As T_getifconfig_ex
    Public Shared ls_getsthigh_ex As T_getsthigh_ex
    Public Shared ls_getstlow_ex As T_getstlow_ex
    Public Shared ls_getstpulse_ex As T_getstpulse_ex
    Public Shared ls_getlinesperframe_ex As T_getlinesperframe_ex
    Public Shared ls_getquadcount_ex As T_getquadcount_ex
    Public Shared ls_getsofttriggertime_ex As T_getsofttriggertime_ex
    Public Shared ls_gettriggerdelay_ex As T_gettriggerdelay_ex
    Public Shared ls_gettriggerwidth_ex As T_gettriggerwidth_ex
    Public Shared ls_getpixelcount_ex As T_getpixelcount_ex
    Public Shared ls_getedgedelay_ex As T_getedgedelay_ex
    Public Shared ls_getadcvref_ex As T_getadcvref_ex
    Public Shared ls_getadcgain_ex As T_getadcgain_ex
    Public Shared ls_getgainmult_ex As T_getgainmult_ex
    Public Shared ls_getgaindiv_ex As T_getgaindiv_ex
    Public Shared ls_getadcoffset_ex As T_getadcoffset_ex
    Public Shared ls_getadcbias_ex As T_getadcbias_ex
    Public Shared ls_savesettings_ex As T_savesettings_ex
    Public Shared ls_reloadsettings_ex As T_reloadsettings_ex
    Public Shared ls_resetsettings_ex As T_resetsettings_ex
    Public Shared ls_getinitstatus_ex As T_getinitstatus_ex
    Public Shared ls_getcomresult_ex As T_getcomresult_ex
    Public Shared ls_getmcuversion_ex As T_getmcuversion_ex
    Public Shared ls_getctgversion_ex As T_getctgversion_ex
    Public Shared ls_gethw1id_ex As T_gethw1id_ex
    Public Shared ls_gethw1version_ex As T_gethw1version_ex
    Public Shared ls_gethw2version_ex As T_gethw2version_ex
#End Region

#Region "String helpers"
    Public Shared Function AnsiPtrToString(value As IntPtr) As String
        If value = IntPtr.Zero Then
            Return Nothing
        End If
        Return Marshal.PtrToStringAnsi(value)
    End Function

    Public Shared Function PtrToAnsi(value As IntPtr) As String
        Return AnsiPtrToString(value)
    End Function

    Public Shared Function GetErrorString(errorCode As UInteger) As String
        If ls_geterrorstring Is Nothing Then
            Return String.Format("Error {0}", errorCode)
        End If
        Return AnsiPtrToString(ls_geterrorstring(errorCode))
    End Function
#End Region

End Class
