在新建的工程中,add一个module,添加声明函数等代码。
如: Public Declare Function AdvDVP_Start Lib "xxx.dll" (ByVal nDevNum As Long,ByVal SwitchingChans As Long,ByVal Main As Long,ByVal hwandPreview As Long) As Long
Xxx为待测试的c++的dll名称。
主程序,直接使用就好了。
当然,也可以用工具直接从c#转到vb.net,哈哈
在Public Class Class1前,添加如下:
Imports System.Runtime.InteropServices ' 用DllImport 需用此命名空间
Imports System.Reflection ' 使用Assembly 类需用此命名空间
Imports System.Reflection.Emit ' 使用ILGenerator 需用此命名空间
Private Declare Auto Function LoadLibrary Lib "kernel32" _
(ByVal LibFilePath As String) As Integer
Private Declare Function GetProcAddress Lib "kernel32" _
(ByVal ModuleHandle As Integer,ByVal ProcName As String) _
As Integer
Private Declare Function FreeLibrary Lib "kernel32" _
(ByVal ModuleHandle As Integer) As Integer
Public Enum ModePass
ByValue = &H1
ByAdd = &H2
End Enum
Private hmodule As IntPtr = IntPtr.Zero
Private farProc As IntPtr = IntPtr.Zero
Public Sub LoadDll(ByVal lpFileName As String)
hmodule = LoadLibrary(lpFileName)
If hmodule = IntPtr.Zero Then
Console.WriteLine("没有找到:" & lpFileName)
Exit Sub
Else
Console.WriteLine("装入:" & lpFileName & "成功!")
End If
End Sub
Public Sub LoadFun(ByVal lpProcName As String)
If hmodule = IntPtr.Zero Then
Console.WriteLine("函数库模块的句柄为空,请确保已进行LoadDll 操作")
Exit Sub
Else
farProc = GetProcAddress(hmodule,lpProcName)
If farProc = IntPtr.Zero Then
Console.WriteLine("没有找到:" & lpProcName & " 这个函数的入口点")
Exit Sub
Else
Console.WriteLine("找到:" & lpProcName & " 这个函数的入口点,并载入成功!")
End If
End If
End Sub
Public Sub UnLoadDll()
'FreeLibrary(Me.hmodule)
Me.hmodule = IntPtr.Zero
Me.farProc = IntPtr.Zero
Console.WriteLine("清除完毕!")
End Sub
Public Function Invoke(ByVal ObjArray_Parameter As Object(),ByVal TypeArray_ParameterType As Type(),ByVal ModePassArray_Parameter As ModePass(),ByVal Type_Return As Type) As Object
Dim MyAssemblyName As New AssemblyName
Dim MyAssemblyBuilder As AssemblyBuilder
Dim MyModuleBuilder As ModuleBuilder
Dim MyMethodBuilder As MethodBuilder
Dim IL As ILGenerator
Dim MyMethodInfo As MethodInfo
If hmodule = IntPtr.Zero Then
Throw (New Exception(" 函数库模块的句柄为空,请确保已进行LoadDll 操作!"))
End If
If farProc = IntPtr.Zero Then
Throw (New Exception(" 函数指针为空,请确保已进行LoadFun 操作!"))
End If
If ObjArray_Parameter.Length <> ModePassArray_Parameter.Length Then
Throw (New Exception(" 参数个数及其传递方式的个数不匹配."))
End If
'
Dim i As Integer
MyAssemblyName.Name = "InvokeFun" '程序集的名称
MyAssemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(MyAssemblyName,AssemblyBuilderAccess.Run) '使用指定的名称、访问模式和自定义属性定义动态程序集
MyModuleBuilder = MyAssemblyBuilder.DefineDynamicModule("InvokeDll")
MyMethodBuilder = MyModuleBuilder.DefineGlobalMethod("MyFun",MethodAttributes.Public Or MethodAttributes.Static,Type_Return,TypeArray_ParameterType)
IL = MyMethodBuilder.GetILGenerator()
For i = 0 To ObjArray_Parameter.Length - 1
Select Case ModePassArray_Parameter(i)
Case ModePass.ByValue
IL.Emit(OpCodes.Ldarg,i)
Exit For
Case ModePass.ByAdd
IL.Emit(OpCodes.Ldarga,i)
Exit For
Case Else
Throw (New Exception(" 第" + (i + 1).ToString() + " 个参数没有给定正确的传递方式."))
End Select
Next
If IntPtr.Size = 4 Then
IL.Emit(OpCodes.Ldc_I4,farProc.ToInt32())
ElseIf IntPtr.Size = 8 Then
IL.Emit(OpCodes.Ldc_I8,farProc.ToInt64())
Else
Throw New PlatformNotSupportedException()
End If
IL.EmitCalli(OpCodes.Calli,CallingConvention.StdCall,TypeArray_ParameterType)
IL.Emit(OpCodes.Ret) '返回值
MyModuleBuilder.CreateGlobalFunctions()
MyMethodInfo = MyModuleBuilder.GetMethod("MyFun")
Dim ret As Integer
Try
ret = MyMethodInfo.Invoke(Nothing,ObjArray_Parameter) '调用方法,并返回其值
Catch ex As Exception
MsgBox(ex.ToString)
End Try
'Return MyMethodInfo.Invoke(Nothing,ObjArray_Parameter) '调用方法,并返回其值
Return ret
End Function
添加一个button,和一个name为txRet的textBox,双击按钮,并添加如下代码:
Dim ret As Integer
Dim myDLD As New Class1
myDLD.LoadDll("DVP7010B.dll")
myDLD.LoadFun("AdvDVP_InitSDK")
Dim Parameters() As Object = {}
Dim ParameterTypes() As Type = {}
Dim themode() As Class1.ModePass = {}
Dim Type_Return As Type
Type_Return = GetType(Integer)
ret = myDLD.Invoke(Parameters,ParameterTypes,themode,Type_Return)
txRet.Text = ret.ToString()
If ret <> 1 Then
End If
If ret = 1 Then
MsgBox("InitSDK sucessed !")
End If