P / Invoke动态DLL搜索路径

时间:2010-03-09 19:00:39

标签: c# .net pinvoke dllimport

我有一个现有的应用程序P / Invokes到与应用程序本身位于同一目录中的DLL。

现在(由于佳能生产了最疯狂的API之一)我需要支持这个API的两个版本,并在运行时确定我应该使用哪个(旧的或新的)。由于DLL具有相同的名称(第一个加载具有相同名称的其他DLL,因此只重命名第一个将无法帮助我)我必须将它们保存在不同的目录中。

因此我的问题是:我有什么选择来控制DllImport声明中给出的DLL所使用的目录?

我想我可以尝试这两个想法中的任何一个:

1)在执行第一次P / Invoke之前使用“SetDllDirectory”设置我想要的目录,然后重置它。

2)使用“LoadLibraryEx”手动加载所需的DLL,并希望这样做。

但是,还有“.NET:ish方式”首先尝试吗?

更新:我意识到我可以在两个单独的.Net程序集中填充对DLL的所有访问权限,然后将它们中的每一个放在一个带有相应API文件的单独目录中。然后我可以动态加载正确的.Net程序集,并自动加载正确的DLL。有什么理由不起作用吗?

我能想到一个:我将如何调试这些东西?有可能告诉Visual Studio一个程序集(包含在我的解决方案中)应该放在一个子目录中并从那里进行调试吗?

3 个答案:

答案 0 :(得分:10)

我表示哀悼,我见过其中一个API,确实令人震惊。更大的问题是你需要能够说服Windows找到DLL。它们不在您的.exe目录中,因此默认设置不起作用。使用SetDllDirectory()可以工作,使用Environment.CurrentDirectory也可以。 LoadLibrary无法工作,P / Invoke编组器将使用LoadLibrary本身。

如果它是一个选项,您可以为两个P / Invoke声明使用不同的名称,使用DllImport()构造函数的不同参数并使用EntryPoint属性。听起来不会那样。

答案 1 :(得分:2)

我认为第二个选项可行,但需要编写大量代码来管理.net中的dll加载。

第一个也可能有用,但我要么不喜欢它。

以下是我的建议:您可以在DllImport [DllImport(@"C:\dll\a32.dll"]

中指定完整路径(可能是相对路径)

答案 2 :(得分:1)

您的第一个选项(P / Invoke with SetDllDirectory)是我个人喜欢的选项。不幸的是,没有“.NETish”方法来处理加载本机DLL ......这确实很有意义。