如何在运行时指定[DllImport]路径?
实际上,我有一个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”参数。
所以我的问题是::在这种情况下可以做什么?
回答:
与其他答案的建议相反,使用DllImport
属性仍然是正确的方法。
老实说,我不明白为什么您不能像世界上其他所有人一样,并指定DLL 的 相对
路径。是的,在不同人的计算机上,应用程序的安装路径会有所不同,但这基本上是部署的通用规则。该DllImport
机制的设计考虑到这一点。
实际上,它甚至DllImport
无法解决问题。无论您是否使用方便的托管包装程序(P / Invoke
marshaller只是调用LoadLibrary
),它都是控制事情的本机Win32
DLL加载规则。这些规则在这里详细列出,但是重要的规则在这里摘录:
- 如果内存中已经加载了具有相同模块名称的DLL,则系统将使用已加载的DLL,无论它位于哪个目录中。系统都不会搜索该DLL。
*
如果该DLL在运行该应用程序的Windows版本的已知DLL列表中,则系统使用其已知DLL的副本(以及已知DLL的从属DLL,如果有的话)。系统不搜索DLL。
- 从中加载应用程序的目录。
- 系统目录。使用该
GetSystemDirectory
函数获取此目录的路径。- 16位系统目录。没有获取该目录路径的函数,但会对其进行搜索。
- Windows目录。使用该
GetWindowsDirectory
函数获取此目录的路径。- 当前目录。
6.
PATH
环境变量中列出的目录。请注意,这不包括“应用程序路径”注册表项指定的每个应用程序路径。计算DLL搜索路径时不使用“应用程序路径”键。
因此,除非您为DLL命名与系统DLL相同(除非在任何情况下都不应该这样做),否则默认搜索顺序将开始在加载应用程序的目录中查找。如果在安装过程中将DLL放在此处,则会找到它。如果仅使用相对路径,所有复杂的问题都会消失。
写就好了:
[DllImport("MyAppDll.dll")] // relative path; just give the DLL's namestatic extern bool MyGreatFunction(int myFirstParam, int mySecondParam);
但是,如果由于某种原因该方法 不起作用
,并且您需要强制应用程序在DLL的其他目录中查找,则可以使用SetDllDirectory
函数修改默认的搜索路径。
请注意,根据文档:
调用后
SetDllDirectory
,标准DLL搜索路径为:
- 从中加载应用程序的目录。
lpPathName
参数指定的目录。- 系统目录。使用该
GetSystemDirectory
函数获取此目录的路径。- 16位系统目录。没有获取该目录路径的函数,但会对其进行搜索。
- Windows目录。使用该
GetWindowsDirectory
函数获取此目录的路径。PATH
环境变量中列出的目录。
因此,只要您在第一次调用从DLL导入的函数之前调用此函数,就可以修改用于定位DLL的默认搜索路径。当然,这样做的好处是您可以将 动态
值传递给在运行时计算的该函数。使用DllImport
属性是不可能的,因此您仍将在此处使用相对路径(仅DLL的名称),并依靠新的搜索顺序为您找到它。
您必须P /调用此功能。声明看起来像这样:
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]static extern bool SetDllDirectory(string lpPathName);
以上是 如何在运行时指定[DllImport]路径? 的全部内容, 来源链接: utcz.com/qa/432180.html