[英]How to use a dll written for VB.Net in C#
我有问题要问。
我有一个dll文件,用于在USB上读写数据。 要在VB.Net中使用dll,需要集成一个.vb文件,该文件与该dll文件进行接口以使用其功能,属性等。
我需要在C#项目中使用此dll。 这可能吗? 如果是,我该如何实现?
形式为类的代码:
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
如何将表单实例发送到HIDDLLInterface(对我而言等效)?
接口类代码如下:
导入系统导入System.Threading导入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
假设VB.NET代码符合CLS ,则只需将对它的引用添加到C#项目中。
此时,名称空间和DLL中的所有公共成员将对您的C#代码可用。
您的设计中存在耦合问题。 为了解决此问题,我建议以下内容:
HIDDLLInterface
转换为在构造函数中采用IntPtr
的类。 在构造函数中,调用hidConnect
。 IDisposable
。 VB IDE提供了不错的默认实现。 因为您正在处理非托管资源,所以您可能还应该取消对它添加的终结器的注释。 HWND
或Hsomething
,则应使用IntPtr
而不是Integer
来更紧密地匹配参数的含义。 之后,该类应如下所示:
Public Class HIDController
Implements IDisposable
#Region "Constructor"
Public Sub New(handle As IntPtr)
If Not hidConnect(handle) Then
'consider a custom exception type here. You may also get
'more info about the failure from GetLastError.
Throw New Exception("Connection failed")
End If
_handle = handle
_prevWinProc = DelegateSetWindowLong(handle, GWL_WNDPROC, AddressOf Me.WinProc)
End Sub
#End Region
#Region "IDisposable Support"
Private disposedValue As Boolean
Protected Overridable Sub Dispose(disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
' TODO: dispose managed state (managed objects).
End If
' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
DisconnectFromHID()
End If
Me.disposedValue = True
End Sub
Protected Overrides Sub Finalize()
Dispose(False)
MyBase.Finalize()
End Sub
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
Private _handle As IntPtr
Private ReadOnly _prevWinProc As IntPtr
'on one hand, you are not supposed to throw from Dispose/Finalize, but
'on the other hand, I don't know what you would do instead to signal failure.
Private Sub DisconnectFromHID()
'do not disconnect if you did not connect
If _handle = IntPtr.Zero Then Exit Sub
If Not hidDisconnect() Then
'see above about custom exception type
Throw New Exception("Disconnect failed")
End If
SetWindowLong(_handle, GWL_WNDPROC, _prevWinProc)
_handle = IntPtr.Zero
End Sub
Private Function WinProc(ByVal pHWnd As IntPtr, ByVal pMsg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
If pMsg = WM_HID_EVENT Then
Select Case wParam.ToInt32()
Case NOTIFY_PLUGGED
OnPlugged(lParam)
Case NOTIFY_UNPLUGGED
OnUnplugged(lParam)
Case NOTIFY_CHANGED
OnChanged()
Case NOTIFY_READ
OnRead(lParam)
End Select
End If
WinProc = CallWindowProc(FPrevWinProc, pHWnd, pMsg, wParam, lParam)
End Function
#Region "USB events"
Private Sub OnPlugged(lParam As IntPtr)
RaiseEvent Plugged(Me, New ParamEventArgs(lParam))
End Sub
Public Event Plugged As EventHandler(Of ParamEventArgs)
Private Sub OnUnplugged(lParam As IntPtr)
RaiseEvent Unplugged(Me, New ParamEventArgs(lParam))
End Sub
Public Event Unplugged As EventHandler(Of ParamEventArgs)
Private Sub OnChanged()
RaiseEvent Changed(Me, EventArgs.Empty)
End Sub
Public Event Changed As EventHandler
Private Sub OnRead(lParam As IntPtr)
RaiseEvent Read(Me, New ParamEventArgs(lParam))
End Sub
Public Event Read As EventHandler(Of ParamEventArgs)
#End Region
'other constants and declarations I did not copy.
End Class
Public Class ParamEventArgs
Inherits EventArgs
Public Sub New(param As IntPtr)
_param = param
End Sub
Private _param As IntPtr
Public ReadOnly Property Param() As IntPtr
Get
Return _param
End Get
End Property
End Class
从那里,您可以更改表单以在Load / Close事件中创建并处理此类的实例,并挂接处理程序。 您将必须更改表单方法以匹配事件签名,但这应该很简单。
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
_controller = new HIDController(Me.Handle)
AddHandler _controller.Plugged, AddressOf Me.OnPlugged
'similarly for other events
End Sub
Private Sub Form1_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
If _controller IsNot Nothing Then _controller.Dispose()
End Sub
现在,该类应该易于从C#dll使用。 只需将HIDController
编译为VB.NET中的程序集,然后从C#项目中引用该dll(并导入任何所需的名称空间)。 不要忘记也复制本机dll。 C#编译器将仅自动复制VB dll。 现在,任何可以提供窗口句柄的类都可以创建HIDController
并处理其事件,而无需控制器知道托管它的类。
PS:我建议在VB中编码时启用Option Strict。 另外,您可能希望研究DllImport
以将功能从本机库导入到.NET项目中,因为这就是大多数示例的做法,并且将使在VB和C#之间进行复制变得更加容易。
引用VB项目中的C#dll(或将dll放到/ bin文件夹中)
如您所知,您需要将表单类中的VB.NET代码改编为C#。
在“回答您的问题”而不是背后的VB.NET表单调用中:
iConnectToHID(Me)
你会用
iConnectToHID(this);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.