C 当缺少依赖项时,如何使LoadLibrary显示错误对话框
假设我们有两个动态库C 当缺少依赖项时,如何使LoadLibrary显示错误对话框,c,winapi,dll,windows-10,loadlibrary,C,Winapi,Dll,Windows 10,Loadlibrary,假设我们有两个动态库libfoo.dll和libbar.dll,假设libbar.dll依赖于libfoo.dll。此外,我们还编译了一个可执行文件test.exe,它使用WinAPI函数LoadLibrary()加载我们的libbar.dll 如果我们在Windows XP上运行text.exe时缺少libfoo.dll,LoadLibrary()会显示对话框警报,而不是libfoo.dll实际缺少,并将LastError设置为ERROR\u MOD\u NOT\u FOUND(126) 如果
libfoo.dll
和libbar.dll
,假设libbar.dll
依赖于libfoo.dll
。此外,我们还编译了一个可执行文件test.exe
,它使用WinAPI函数LoadLibrary()
加载我们的libbar.dll
如果我们在Windows XP上运行text.exe
时缺少libfoo.dll
,LoadLibrary()
会显示对话框警报,而不是libfoo.dll
实际缺少,并将LastError
设置为ERROR\u MOD\u NOT\u FOUND
(126)
如果我们在Windows 10上以相同的条件运行相同的text.exe
,LoadLibrary()
将LastError
设置为ERROR\u MOD\u NOT\u FOUND
仅显示对话框
在这两种情况下,ErrorMode
均为0。那么,是否有可能在调用进程LoadLibrary()
中捕获缺少依赖项的名称,或者至少,如何在Windows 10上创建LoadLibrary()
显示错误对话框
下面是一个示例代码(使用MinGW):
富科
编译时使用:gcc foo.c-o libfoo.dll-fPIC-shared
酒吧c
编译时使用:gcc bar.c-o libbar.dll-fPIC-shared-L-lfoo
测试c
#包括
#包括
类型定义内部(*pfn)(内部a、内部b);
int main()
{
设置错误模式(0);
HMODULE hmod=LoadLibrary(“libbar.dll”);
如果(!hmod)
{
fprintf(stderr,“加载库%d时出错”,GetLastError());
返回1;
}
pfn bar=(pfn)GetProcAddress(hmod,“bar”);
如果(巴)
{
fprintf(标准输出,“条(3,1)=%d\n”,条(3,1));
}
其他的
{
fprintf(stderr,“无法加载条操作\n”);
}
免费图书馆;
返回0;
}
编译时使用:
gcc test.c-o test
目前,似乎对提出的问题没有优雅的解决方案
正如@DavidHeffernan在对原始帖子的评论中所指出的,这个问题应该在一个根本不同的层面上得到解决。由于LoadLibrary()
的行为与应有的行为相同,关键在于正确的安装和错误处理
但是,如果需要显式捕获动态加载库缺少的依赖项,则可以应用@IInspectable和@eryksun提供的技术:
- 为将要动态加载的库启用。这种方法为每个依赖模块提供了助手回调,因此可以就地处理缺少的依赖项。这种方法的主要缺点是,应该使用适当的链接器标志重新编译目标库李>
- 可以编写从应用程序转储调试字符串的helper实用程序(有关详细信息,请参阅原始帖子的@eryksun注释)。缺点:除了需要编写额外的模块外,它还包括一些注册表操作
NtRaiseHardError
。因此,您可以查看错误对话框和设置错误模式。但是win10不能调用NtRaiseHardError
more。因此,无错误对话框和错误模式在此不起作用
int foo(int a, int b)
{
return a + b;
}
int foo(int a, int b);
int bar(int a, int b)
{
return foo(a, b);
}
#include <windows.h>
#include <stdio.h>
typedef int (*pfn)(int a, int b);
int main()
{
SetErrorMode(0);
HMODULE hmod = LoadLibrary("libbar.dll");
if(!hmod)
{
fprintf(stderr, "error loading library %d\n", GetLastError());
return 1;
}
pfn bar = (pfn)GetProcAddress(hmod, "bar");
if(bar)
{
fprintf(stdout, "bar(3, 1) = %d\n", bar(3, 1));
}
else
{
fprintf(stderr, "can't load bar foonction\n");
}
FreeLibrary(hmod);
return 0;
}