【发布时间】:2014-01-02 15:37:04
【问题描述】:
我有一些代码可以在 Unix(Linux 和 Solaris)和 Windows(确切地说是 7)上运行,但不能在 Windows CE 上运行。该代码实现了一个插件框架,并且需要将符号从可执行文件导出到加载的插件中。我无法从主可执行文件中获取加载的插件 (DLL) 来解析符号。
我已将接口简化为主可执行文件中的单个函数,其定义如下:
extern "C" __declspec( dllexport )
const char * translate_name( const char *key ) {
...
}
如果我在可执行文件上运行 Dumpbin /EXPORTS,我会将其视为导出符号之一:
81 50 00001474 translate_name = @ILT+1135(_translate_name)
插件需要导出两个函数 xxxLoadPlugin 和 xxxUnloadPlugin 加载后主可执行文件将调用它们以允许它们互连。 xxx 替换为约定的名称前缀(通常是 dll 或 .so 名称)。我有一个测试项目,它创建:
extern "C" __declspec( dllexport ) int testRegisterLibrary( ) {
return 0;
}
extern "C" __declspec( dllexport ) int testUnregisterLibrary( ) {
return 0;
}
如果我编译并运行这个模块,一切都会按预期工作。我可以加载 dll,并在调试器中遍历函数。
如果我添加引用 translate_name 的代码,例如:
extern "C" __declspec( dllimport ) const char * translate_name( const char *key );
extern "C" __declspec( dllexport ) int testRegisterLibrary( ) {
translate_name("test");
return 0;
}
extern "C" __declspec( dllexport ) int testUnregisterLibrary( ) {
return 0;
}
DLL 现在将无法加载。使用 dumpbin /IMPORTS 检查创建的 DLL 我看到了:
50 translate_name
translate_name 是从我的主可执行文件导入的唯一符号。如果我尝试使用 GetProcAddress 而不是依赖链接器,如下所示:
extern "C" __declspec( dllexport ) int testRegisterLibrary( ) {
HMODULE mainModule = GetModuleHandle(NULL); //handle for main executable
void *ptr = (void *)GetProcAddress(L"translate_name");
return 0;
}
extern "C" __declspec( dllexport ) int testUnregisterLibrary( ) {
return 0;
}
DLL 加载,但“ptr”的值为 NULL(在调试器中检查)。我也尝试过 GetProcAddressA("translate_name"),并使用 "_translate_name" 获得相同的结果。
鉴于此,在 Windows CE 中初始加载程序通过后,可执行文件导出的符号似乎没有保留。同样,这适用于任何正常的 Windows 环境。 Windows CE 是否缺少某些设置?为什么 GetProcAddress 在 dumpbin 说导出的可执行文件中找不到符号? Windows CE 加载程序是否隐藏或删除了符号?
【问题讨论】: