在 VB.NET 中动态声明第三方 DLL

Declaring third party DLL dynamically in VB.NET

我在不同环境中导入 DLL 时遇到问题。
我必须检查 Windows 平台并导入将放置在 C:\\Program Files\\(对于 32-bit)或 C:Program Files (x86)\\(对于 64-bit)中的第三方 DLL。

之前的代码是这样写的:

1
2
3
4
Declare Function RDRCConnect Lib"c:\\program files\\TP-DLL\
DRCAP32.DLL"
(ByVal lpszServerName As String, ByVal lNetConnType As Integer, ByVal lpszParam1 As String, ByVal lpszParam2 As String, ByVal lpszParam3 As String, ByRef lNetConn As Integer, ByRef lNetErr As Integer) As Integer  
Declare Function RDRCDisconnect Lib"c:\\program files\\TP-DLL\
DRCAP32.DLL"
(ByVal lNetConn As Integer, ByRef lNetErr As Integer) As Integer

...我改为使用属性:

1
2
3
4
5
6
Private Const CheminDLL As String ="C:\\Program Files\\TP-DLL\
DRCAP32.DLL"


<System.Runtime.InteropServices.DllImport(CheminDLL)>
Private Shared Function RDRCConnect(ByVal lpszServerName As String, ByVal lNetConnType As Integer, ByVal lpszParam1 As String, ByVal lpszParam2 As String, ByVal lpszParam3 As String, ByRef lNetConn As Integer, ByRef lNetErr As Integer) As Integer
End Function

在这种情况下,一旦 DLLImport 需要一个常量作为参数,我该如何动态更改 DLL 路径?


没有办法将除常量之外的任何东西传递给属性,因为根据定义,属性是在编译时评估的,而不是在运行时评估的。可能有更好的选择,但我可以给你的一个选择是为每个版本创建单独的导入:

1
2
3
4
5
6
7
8
9
<DllImport("C:\\Program Files\\TP-DLL\
DRCAP32.DLL"
, EntryPoint :="RDRCConnect")>
Private Shared Function RDRCConnect32(ByVal lpszServerName As String, ByVal lNetConnType As Integer, ByVal lpszParam1 As String, ByVal lpszParam2 As String, ByVal lpszParam3 As String, ByRef lNetConn As Integer, ByRef lNetErr As Integer) As Integer
End Function

<DllImport("C:\\Program Files (x86)\\TP-DLL\
DRCAP32.DLL"
, EntryPoint :="RDRCConnect")>
Private Shared Function RDRCConnect64(ByVal lpszServerName As String, ByVal lNetConnType As Integer, ByVal lpszParam1 As String, ByVal lpszParam2 As String, ByVal lpszParam3 As String, ByRef lNetConn As Integer, ByRef lNetErr As Integer) As Integer
End Function

然后您需要在每次调用该方法时选择适当调用哪一个。


如果 dll 相同(相同的名称和签名)但只是在不同的位置,那么您可以使用在运行时确定的 dll 的完整路径显式地 p/invoke LoadLibrary。只要在调用任何导出的 API 之前执行此操作,只要导入中的 dll 名称相同,它将使用已加载的 API。


几天前我偶然发现了这个问题,当时我遇到了与您类似的问题,这让我走上了正确的道路。在这里寻找它。