事实上,我有一个 C++(工作)DLL,我想将它导入到我的 C# 项目中以调用它的函数。
当我指定 DLL 的完整路径时,它确实有效,如下所示:
string str = "C:\\Users\\userName\\AppData\\Local\\myLibFolder\\myDLL.dll";
[DllImport(str, CallingConvention = CallingConvention.Cdecl)]
public static extern int DLLFunction(int Number1, int Number2);
问题是它将是一个可安装的项目,因此用户的文件夹将不一样(例如:pierre、paul、jack、mum、dad…),具体取决于运行它的计算机/会话。
所以我希望我的代码更通用一点,就像这样:
/*
goes right to the temp folder of the user
"C:\\Users\\userName\\AppData\\Local\\temp"
then go to parent folder
"C:\\Users\\userName\\AppData\\Local"
and finally go to the DLL's folder
"C:\\Users\\userName\\AppData\\Local\\temp\\myLibFolder"
*/
string str = Path.GetTempPath() + "..\\myLibFolder\\myDLL.dll";
[DllImport(str, CallingConvention = CallingConvention.Cdecl)]
public static extern int DLLFunction(int Number1, int Number2);
最重要的是“DllImport”需要 DLL 目录的“const string”参数。
所以我的问题是:: 在这种情况下可以做什么?
原文由 Jsncrdnl 发布,翻译遵循 CC BY-SA 4.0 许可协议
与其他一些答案的建议相反,使用
DllImport
属性仍然是正确的方法。老实说,我不明白为什么你不能像世界上其他人一样做,并指定你的 DLL 的 相对 路径。是的,您的应用程序在不同人的计算机上的安装路径不同,但这基本上是部署时的通用规则。
DllImport
机制的设计考虑了这一点。事实上,处理它的甚至不是
DllImport
。无论您是否使用方便的托管包装器(P/Invoke marshaller 只调用LoadLibrary
),它都是本机 Win32 DLL 加载规则来管理事物。 此处 详细列举了这些规则,但此处摘录了重要的规则:因此,除非您将 DLL 命名为与系统 DLL 相同的名称(在任何情况下您显然都不应该这样做),否则默认搜索顺序将开始在加载应用程序的目录中查找。如果您在安装过程中将 DLL 放在那里,它将被找到。如果您只使用相对路径,所有复杂的问题都会消失。
写吧:
但是,如果由于某种原因这 _不起作用_,并且您需要强制应用程序在不同的目录中查找 DLL,您可以使用
SetDllDirectory
函数 修改默认搜索路径。请注意,根据文档:
所以只要在第一次调用从DLL导入的函数之前调用这个函数,就可以修改用于定位DLL的默认搜索路径。当然,好处是您可以将 动态 值传递给在运行时计算的此函数。这对于
DllImport
属性是不可能的,因此您仍将在那里使用相对路径(仅 DLL 的名称),并依靠新的搜索顺序为您找到它。你必须 P/Invoke 这个函数。声明如下所示: