vb.net静态动态调用c++dll的方法

时间:2021-06-24 14:01:01

vb.net静态调用c++dll的方法:

在新建的工程中,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,哈哈

 

vb.net动态调用c++dll的方法:

在工程中添加一个class。在文件中,添加如下代码:

Public Class Class1前,添加如下:

Imports System.Runtime.InteropServices ' DllImport 需用此命名空间

Imports System.Reflection ' 使用Assembly 类需用此命名空间

Imports System.Reflection.Emit ' 使用ILGenerator 需用此命名空间

Public Class Class1中,添加如下代码:

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, Type_Return, 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,和一个nametxRettextbox双击按钮,并添加如下代码:

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

                    MsgBox("InitSDK failed !")

                End If

                If ret = 1 Then

                    MsgBox("InitSDK sucessed !")

                End If