c++ - 从 DLL 访问 Windows CE .EXE 符号

标签 c++ c windows dll

我有一些代码可以在 Unix(Linux 和 Solaris)和 Windows(准确地说是 7)上运行,但不能在 Windows CE 上运行。这段代码实现了一个插件框架,需要将符号从可执行文件导出到加载的插件中。我无法获取加载的插件 (DLL) 来解析来自主可执行文件的符号。

我已将接口(interface)缩减为主可执行文件中的单个函数,其定义如下:

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 加载程序是否隐藏或删除了符号?

最佳答案

只是为了确认您的发现,这是行不通的。在 MSDN 文档中很难找到确凿的证据表明它不受支持,除了 GetProcAddress() 坚持认为该符号必须由 DLL 导出之外。您无法加载 DLL,当它包含来自 EXE 的导入时,它将失败并显示 ERROR_BAD_EXE_FORMAT。 GetProcAddress() 将始终失败并返回 ERROR_INVALID_HANDLE,即使您将模块句柄强制设置为 EXE 加载地址也是如此。

没有强有力的证据表明加载程序有意剥离 EXE 的导出表,当您使用调试器查看时,它驻留在内存中。它只是断然拒绝看它。

您需要解决这个问题并以不同的方式解决这个问题。除了在单独的 DLL 中分离辅助函数之外,一个明显的解决方法是为 xxxLoadPlugin() 入口点提供一个参数,一个指向辅助函数的函数指针表的指针。常见的IServiceProvider interface在 COM 中使用是一个很好的方法。

关于c++ - 从 DLL 访问 Windows CE .EXE 符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20590709/

相关文章:

php - 127.0.0.1 可访问/工作但本地主机不可访问/不工作

C++ Mac OS X 10.11.2 vm_read 给出错误的值

c - Bison 优先级没用?它不起作用

c - 从文件读取时的制表符宽度

java - Windows Azure cspack.exe 是开源的吗?

c - 如何仅使用 C 列出和操作 Windows 文件?

c++ - osx 语言环境错误?

c++ - 查找两个字符串中的共同字符

c++ - opengl 3d纹理问题

c - 相对于编译器的输出变化