I have question to ask.
I have a dll file written for reading&writing data on USB. To use dll in VB.Net, one needs to integrate a .vb file which interface to that dll file to use its functions, properties etc..
What I need is to use this dll in a C# project. is this possible? if it's, how can I achieve it?
The Code in form Class:
Public Class frmUSB
' vendor and product IDs
Private Const VendorID As Integer = &H1234 'Replace with your device's
Private Const ProductID As Integer = &H1234 'product and vendor IDs
' read and write buffers
Private Const BufferInSize As Integer = 1 'Size of the data buffer coming IN to the PC
Private Const BufferOutSize As Integer = 1 'Size of the data buffer going OUT from the PC
Dim BufferIn(BufferInSize) As Byte 'Received data will be stored here - the first byte in the array is unused
Dim BufferOut(BufferOutSize) As Byte 'Transmitted data is stored here - the first item in the array must be 0
' ****************************************************************
' when the form loads, connect to the HID controller - pass
' the form window handle so that you can receive notification
' events...
'*****************************************************************
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
' do not remove!
ConnectToHID(Me)
End Sub
'*****************************************************************
' disconnect from the HID controller...
'*****************************************************************
Private Sub Form1_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
DisconnectFromHID()
End Sub
'*****************************************************************
' a HID device has been plugged in...
'*****************************************************************
Public Sub OnPlugged(ByVal pHandle As Integer)
If hidGetVendorID(pHandle) = VendorID And hidGetProductID(pHandle) = ProductID Then
' ** YOUR CODE HERE **
End If
End Sub
'*****************************************************************
' a HID device has been unplugged...
'*****************************************************************
Public Sub OnUnplugged(ByVal pHandle As Integer)
If hidGetVendorID(pHandle) = VendorID And hidGetProductID(pHandle) = ProductID Then
hidSetReadNotify(hidGetHandle(VendorID, ProductID), False)
' ** YOUR CODE HERE **
End If
End Sub
'*****************************************************************
' controller changed notification - called
' after ALL HID devices are plugged or unplugged
'*****************************************************************
Public Sub OnChanged()
' get the handle of the device we are interested in, then set
' its read notify flag to true - this ensures you get a read
' notification message when there is some data to read...
Dim pHandle As Integer
pHandle = hidGetHandle(VendorID, ProductID)
hidSetReadNotify(hidGetHandle(VendorID, ProductID), True)
End Sub
'*****************************************************************
' on read event...
'*****************************************************************
Public Sub OnRead(ByVal pHandle As Integer)
' read the data (don't forget, pass the whole array)...
If hidRead(pHandle, BufferIn(0)) Then
TextBox1.Text = Str(BufferIn(1))
' ** YOUR CODE HERE **
' first byte is the report ID, e.g. BufferIn(0)
' the other bytes are the data from the microcontroller...
End If
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
BufferOut(1) = Val(TextBox2.Text)
hidWriteEx(VendorID, ProductID, BufferOut(0))
End Sub
End Class
What can I use to send an instance of my form to HIDDLLInterface (Equvalent for Me Keyword)?
And the interface class code is given below:
Imports System Imports System.Threading Imports System.Runtime.InteropServices
Module HIDDLLInterface
' this is the interface to the HID controller DLL - you should not
' normally need to change anything in this file.
'
' WinProc() calls your main form 'event' procedures - these are currently
' set to..
'
' MainForm.OnPlugged(ByVal pHandle as long)
' MainForm.OnUnplugged(ByVal pHandle as long)
' MainForm.OnChanged()
' MainForm.OnRead(ByVal pHandle as long)
' HID interface API declarations...
Declare Function hidConnect Lib "mcHID.dll" Alias "Connect" (ByVal pHostWin As Integer) As Boolean
Declare Function hidDisconnect Lib "mcHID.dll" Alias "Disconnect" () As Boolean
Declare Function hidGetItem Lib "mcHID.dll" Alias "GetItem" (ByVal pIndex As Integer) As Integer
Declare Function hidGetItemCount Lib "mcHID.dll" Alias "GetItemCount" () As Integer
Declare Function hidRead Lib "mcHID.dll" Alias "Read" (ByVal pHandle As Integer, ByRef pData As Byte) As Boolean
Declare Function hidWrite Lib "mcHID.dll" Alias "Write" (ByVal pHandle As Integer, ByRef pData As Byte) As Boolean
Declare Function hidReadEx Lib "mcHID.dll" Alias "ReadEx" (ByVal pVendorID As Integer, ByVal pProductID As Integer, ByRef pData As Byte) As Boolean
Declare Function hidWriteEx Lib "mcHID.dll" Alias "WriteEx" (ByVal pVendorID As Integer, ByVal pProductID As Integer, ByRef pData As Byte) As Boolean
Declare Function hidGetHandle Lib "mcHID.dll" Alias "GetHandle" (ByVal pVendoID As Integer, ByVal pProductID As Integer) As Integer
Declare Function hidGetVendorID Lib "mcHID.dll" Alias "GetVendorID" (ByVal pHandle As Integer) As Integer
Declare Function hidGetProductID Lib "mcHID.dll" Alias "GetProductID" (ByVal pHandle As Integer) As Integer
Declare Function hidGetVersion Lib "mcHID.dll" Alias "GetVersion" (ByVal pHandle As Integer) As Integer
Declare Function hidGetVendorName Lib "mcHID.dll" Alias "GetVendorName" (ByVal pHandle As Integer, ByVal pText As String, ByVal pLen As Integer) As Integer
Declare Function hidGetProductName Lib "mcHID.dll" Alias "GetProductName" (ByVal pHandle As Integer, ByVal pText As String, ByVal pLen As Integer) As Integer
Declare Function hidGetSerialNumber Lib "mcHID.dll" Alias "GetSerialNumber" (ByVal pHandle As Integer, ByVal pText As String, ByVal pLen As Integer) As Integer
Declare Function hidGetInputReportLength Lib "mcHID.dll" Alias "GetInputReportLength" (ByVal pHandle As Integer) As Integer
Declare Function hidGetOutputReportLength Lib "mcHID.dll" Alias "GetOutputReportLength" (ByVal pHandle As Integer) As Integer
Declare Sub hidSetReadNotify Lib "mcHID.dll" Alias "SetReadNotify" (ByVal pHandle As Integer, ByVal pValue As Boolean)
Declare Function hidIsReadNotifyEnabled Lib "mcHID.dll" Alias "IsReadNotifyEnabled" (ByVal pHandle As Integer) As Boolean
Declare Function hidIsAvailable Lib "mcHID.dll" Alias "IsAvailable" (ByVal pVendorID As Integer, ByVal pProductID As Integer) As Boolean
' windows API declarations - used to set up messaging...
Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Integer, ByVal hwnd As Integer, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
(ByVal hwnd As Integer, ByVal nIndex As Integer, ByVal dwNewLong As Integer) As Integer
Delegate Function SubClassProcDelegate(ByVal hwnd As Integer, ByVal msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
Public Declare Function DelegateSetWindowLong Lib "USER32.DLL" Alias "SetWindowLongA" _
(ByVal hwnd As Integer, ByVal attr As Integer, ByVal lval As SubClassProcDelegate) As Integer
' windows API Constants
Public Const WM_APP As Integer = 32768
Public Const GWL_WNDPROC As Short = -4
' HID message constants
Private Const WM_HID_EVENT As Decimal = WM_APP + 200
Private Const NOTIFY_PLUGGED As Short = 1
Private Const NOTIFY_UNPLUGGED As Short = 2
Private Const NOTIFY_CHANGED As Short = 3
Private Const NOTIFY_READ As Short = 4
' local variables
Private FPrevWinProc As Integer ' Handle to previous window procedure
Private FWinHandle As Integer ' Handle to message window
Private Ref_WinProc As New SubClassProcDelegate(AddressOf WinProc)
Private HostForm As Object
' Set up a windows hook to receive notification
' messages from the HID controller DLL - then connect
' to the controller
Public Function ConnectToHID(ByRef targetForm As Form) As Boolean
Dim pHostWin As Integer = targetForm.Handle.ToInt32
FWinHandle = pHostWin
pHostWin = hidConnect(FWinHandle)
FPrevWinProc = DelegateSetWindowLong(FWinHandle, GWL_WNDPROC, Ref_WinProc)
HostForm = targetForm
End Function
' Unhook from the HID controller and disconnect...
Public Function DisconnectFromHID() As Boolean
DisconnectFromHID = hidDisconnect
SetWindowLong(FWinHandle, GWL_WNDPROC, FPrevWinProc)
End Function
' This is the procedure that intercepts the HID controller messages...
Private Function WinProc(ByVal pHWnd As Integer, ByVal pMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
If pMsg = WM_HID_EVENT Then
Select Case wParam
' HID device has been plugged message...
Case Is = NOTIFY_PLUGGED
HostForm.OnPlugged(lParam)
' HID device has been unplugged
Case Is = NOTIFY_UNPLUGGED
HostForm.OnUnplugged(lParam)
' controller has changed...
Case Is = NOTIFY_CHANGED
HostForm.OnChanged()
' read event...
Case Is = NOTIFY_READ
HostForm.OnRead(lParam)
End Select
End If
' next...
WinProc = CallWindowProc(FPrevWinProc, pHWnd, pMsg, wParam, lParam)
End Function
End Module
You have a coupling problem in your design. To deal with this problem, I would recommend the following:
HIDDLLInterface
into a class that takes anIntPtr
in the constructor. In the constructor, callhidConnect
.IDisposable
. The VB IDE gives a decent default implementation. Because you are dealing with unmanaged resources, you should probably also uncomment the finalizer it adds.HWND
orHsomething
, you should useIntPtr
instead ofInteger
to more closely match the meaning of the argument.After that, the class should look something like this:
From there, you can change your form to create and dispose an instance of this class in the Load/Close events and hook the handlers. You will have to change your form methods to match the event signatures, but this should be straightforward.
Now the class should be simple to use from a C# dll. Simply compile the
HIDController
into an assembly in VB.NET and then reference that dll from your C# project (and import any needed namespace). Don't forget to copy the native dll as well; the C# compiler will only copy the VB dll automatically. Any class that can provide a window handle can now create theHIDController
and handle its events without the controller knowing which class is hosting it.PS: I would recommend turning on Option Strict when coding in VB. Also, you may want to look into
DllImport
for importing functions from native libraries into .NET projects, as that is how most examples will be and will make it easier to copy between VB and C#.Assuming the VB.NET code is CLS compliant, you can simply add a reference to it to your C# project.
At this point, the namespace and all public members in the DLL will be available to your C# code.
Reference the C# dll in the VB project (or just drop the dll into the /bin folder)
As you know, you need to adapt the VB.NET code in the form class to C#.
In Answer to your question instead of a call from VB.NET Form codebehind:
You would use