【发布时间】:2014-03-01 08:43:26
【问题描述】:
我正在为 PostgreSQL 项目的 Windows 支持中的一个有趣的新问题寻找解决方案。
当插件 DLL 使用 LoadLibrary 调用加载到主可执行文件中时,他们希望动态链接器解析对 postgres.exe 公开的函数和全局变量的引用。
很容易忘记在通过 DLL 访问的 extern 上放置 __declspec(dllimport) 注释,或者更确切地说,扩展为它的 PGDLLIMPORT 宏,因为几乎所有 PostgreSQL 开发和测试都发生在 Linux 和OS X,这些东西都不适用。
该项目依靠自动化测试来检测函数上何时缺少__declspec(dllimport),因为这会导致链接器错误。直到昨天,人们还假设全局变量也是如此,但事实并非如此;事实证明,动态链接默默地成功,产生了垃圾结果。
所以 - 我正在寻找有关如何检测和防止此类非法访问的建议,其中全局不是__declspec(dllimport)'ed。
这很复杂,因为在 Windows 上,PostgreSQL 的构建系统会生成 .def 文件,这些文件只是导出所有内容。 (不是我做的,但我无法改变它,是的,我知道)。这意味着即使在构建主可执行文件期间没有PGDLLIMPORT 标记站点__declspec(dllexport),符号仍然会被导出。
想法?当在另一个模块中定义 extern 全局并且 extern 未正确注释 __declspec(dllimport) 时,有什么方法可以让链接器引发运行时错误?
如果项目停止生成 .def 文件,而是使用 PGDLLIMPORT 注释,在编译 .exe 时扩展为 __declspec(dllexport),在编译使用 exe 的 API 的插件时使用 __declspec(dllimport),当符号注释不正确?有没有其他选择?
我目前正在寻找更多信息,我将编写一些测试程序来尝试测试想法,但我远非 Windows 开发专家,我正在寻找一个权威的“如果可能的话,正确的方法。
【问题讨论】:
-
你想让某人更容易导出全局变量???让他们受苦!并禁止将这种做法作为项目指南。替代方案过于简单和优越。
-
@HansPassant 我完全同意,但不幸的是,我目前无法改变这种做法,只能修复任何由此产生的错误。
-
在此处发布后续问题:stackoverflow.com/questions/21593281/…
-
另外,有用的文章(针对特定于 Windows 的位):lurklurk.org/linkers/linkers.html
-
@CraigRinger 那么,这会是三部曲吗?还是可以认为您的问题已完全解决?
标签: c windows winapi dll linker