假设我想在一些DLL中进行一次典型的非托管调用:
[DllImport("unmanaged.dll")]
static extern int SomeFuncion1(int parm);
DllImportAttribute是否根据注册表中的SafeDllSearchMode设置搜索DLL?我在MSDN中找不到任何表明搜索顺序是否遵循“标准搜索顺序”的内容。
答案 0 :(得分:2)
是的,P / Invoke marshaller只使用LoadLibrary()。观察设置。实际上它在SO帖子中是无法证明的,直到你自己尝试,我通过非常肯定没有合理的替代方案得出结论。 LoadLibrary直接属于“硬”API函数的类别。
Fwiw,它永远不会在您的[DllImport]声明中找到该DLL。非托管DLL只有一个路径,它们没有托管程序集属性,如版本,文化,pkt。如果这实际上是具有这些属性的托管程序集,那么您可以使用Assembly.Load()加载它。但是你很难调用静态函数,CLR不支持,每个方法都必须属于一个类。
在该DLL上使用Dumpbin.exe / exports查找实际从该DLL导出的内容。
答案 1 :(得分:1)
哦,我很不耐烦并自己回答,但汉斯在此期间回答了这个问题。
首先,我创建了一个测试工具:
[DllImport("SomeDllThatDoesntExist.dll")]
public static extern void Test();
static void Main()
{
string currentWorkingDirectory = Directory.GetCurrentDirectory();
Console.WriteLine(currentWorkingDirectory);
Directory.SetCurrentDirectory("E:\\foobar");
currentWorkingDirectory = Directory.GetCurrentDirectory();
Console.WriteLine(currentWorkingDirectory);
// Call method in DLL we know doesn't exist.
Test();
}
然后我使用Procmon对其进行监控,Test()
来电的搜索路径顺序为:
这显示它遵守“安全”搜索顺序,因为当前目录是#5而不是#2,因为如果禁用了SafeDllSearchMode。然后我添加了HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\SafeDllSearchMode
注册表值并将其设置为1(禁用),然后再次运行我的测试工具。那么搜索路径实际上是相同的。我不知道我是否搞砸了添加注册表项,但实际上我唯一想知道的是,默认情况下,它是否遵循“安全”搜索顺序路径 - 这意味着当前目录不是'按顺序排列#2。