我想从"Kernel32.dll"调用函数MoveFile。
1)第一种方法:
Imports System.Runtime.InteropServices
Public Class Form1
<DllImport("KERNEL32.DLL", EntryPoint:="MoveFileW", SetLastError:=True, CharSet:=CharSet.Unicode, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)>
Public Shared Function MoveFile(ByVal src As String, ByVal dst As String) As Boolean
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim src As String = "C:\Users\Baha1990\Documents\Visual Studio 2017\Projects\WindowsApp1\TEST FILE\1\MSACCESS.accdb"
Dim dst As String = "C:\Users\Baha1990\Documents\Visual Studio 2017\Projects\WindowsApp1\TEST FILE\2\MSACCESS.accdb"
Dim RetVal As Boolean = MoveFile(src, dst)
End Sub
End Class
它工作得很好
- 第二种方法:
Imports System.Runtime.InteropServices
Public Class Form1
<Runtime.InteropServices.DllImport("kernel32.dll", SetLastError:=True)> Private Shared Function LoadLibrary(ByVal lpFileName As String) As IntPtr
End Function
<Runtime.InteropServices.DllImport("kernel32.dll", SetLastError:=True, CharSet:=Runtime.InteropServices.CharSet.Ansi, ExactSpelling:=True)> Private Shared Function GetProcAddress(ByVal hModule As IntPtr, ByVal procName As String) As IntPtr
End Function
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
Public Delegate Function _MoveFile(ByVal src As String, ByVal dst As String) As Boolean
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim src As String = "C:\Users\Baha1990\Documents\Visual Studio 2017\Projects\WindowsApp1\TEST FILE\1\MSACCESS.accdb"
Dim dst As String = "C:\Users\Baha1990\Documents\Visual Studio 2017\Projects\WindowsApp1\TEST FILE\2\MSACCESS.accdb"
Dim pDll As IntPtr = IntPtr.Zero
pDll = LoadLibrary("kernel32.dll")
Dim pProc2D = GetProcAddress(pDll, "MoveFileW")
Dim MoveFile = Marshal.GetDelegateForFunctionPointer(pProc2D, GetType(_MoveFile))
Dim RetVal = MoveFile.DynamicInvoke(src, dst) 'Here I get boolean as false it should be true
or
Dim RetVal = MoveFile.Method.Invoke(What to pass here in my case?)
End Sub
End Class
所以问题:DLLImport 和 DynamicInvoke 或 Method.Invoke 有什么区别,为什么我使用 DynamicInvoke 失败以及传递给 Method.Invoke 的参数是什么?
好的,在第二种方法中,我发现在这一行:
<UnmanagedFunctionPointer(CallingConvention.StdCall)>
在我编辑为之后需要额外的参数:
<UnmanagedFunctionPointer(CallingConvention.StdCall, SetLastError:=True, CharSet:=CharSet.Unicode)>
Dim RetVal = MoveFile.DynamicInvoke(src, dst) - DynamicInvoke完美运行。
因此,质疑将什么作为参数传递给 Method.Invoke 仍然打开。
好的,我也想出了 Method.Invoke:
暗淡参数 = {src, dst}
Dim RetVal = MoveFile.Method.Invoke(MoveFile, param) - 完美。
因此,似乎所有三种方法都有效并给出了相同的结果,但是这些方法之间有什么优势。谁能解释一下?