检测跨dll边界访问导出全局文件时丢失的_declspec(dllimport)

检测跨dll边界访问导出全局文件时丢失的_declspec(dllimport),c,windows,winapi,dll,linker,C,Windows,Winapi,Dll,Linker,我正在为PostgreSQL项目的Windows支持寻找解决方案 当使用LoadLibrary调用将插件DLL加载到主可执行文件中时,它们希望动态链接器解析对postgres.exe公开的函数和全局变量的引用 很容易忘记在通过DLL访问的外部上放置\u declspec(dllimport)注释,或者更确切地说,扩展到它的PGDLLIMPORT宏,因为几乎所有的PostgreSQL开发和测试都是在Linux和OS X上进行的,这些东西都不适用 该项目依赖于自动测试来检测函数上何时缺少\uu de

我正在为PostgreSQL项目的Windows支持寻找解决方案

当使用
LoadLibrary
调用将插件DLL加载到主可执行文件中时,它们希望动态链接器解析对
postgres.exe
公开的函数和全局变量的引用

很容易忘记在通过DLL访问的
外部
上放置
\u declspec(dllimport)
注释,或者更确切地说,扩展到它的
PGDLLIMPORT
宏,因为几乎所有的PostgreSQL开发和测试都是在Linux和OS X上进行的,这些东西都不适用

该项目依赖于自动测试来检测函数上何时缺少
\uu declspec(dllimport)
,因为这会导致链接器错误。直到昨天,人们还一直认为全球变量也是如此,但事实并非如此;结果表明,动态链接在静默中成功,产生了一个垃圾结果

因此,我正在寻找有关如何检测和防止此类非法访问的建议,而全局访问不是
\uu declspec(dllimport)
'ed

在Windows上,PostgreSQL的构建系统生成只导出所有内容的
.def
文件,这一事实使情况变得复杂。(不是我做的,但我不能改变,是的,我知道)。这意味着,即使在构建主可执行文件期间没有标记站点的
PGDLLIMPORT
(dllexport),符号仍会导出

想法?当另一个模块中定义了
extern
global并且
extern
没有正确地
\u declspec(dllimport)
注释时,有没有办法让链接器抛出运行时错误

如果项目停止生成.def文件,而是在编译.exe时使用扩展到
\uuudeclspec(dllexport)
PGDLLIMPORT
注释,并且在编译使用exe API的插件时使用
\udeclspec(dllimport)
注释,那么在符号注释不正确时会产生链接器错误吗?除此之外还有别的选择吗


我目前正在寻找更多信息,我将编写一些测试程序来尝试测试想法,但我远非Windows开发专家,我正在寻找一种权威的“正确方法”,如果可能的话。

最好的方法是在
.def
文件中向链接器说明导出数据,而不是代码:

EXPORTS
   i1 DATA
   i2 DATA
或者根本不使用
.def
。它优先并默认导出符号为
code

让我们看看当您将插件链接到这种格式错误的
.lib
文件时会发生什么。假设您声明:

   int __declspec(dllimport) i1;
   extern int i2;
这意味着您的
.obj
文件将具有外部依赖项
\uu imp\uu i1
\u i2
。第一个将指向真正导入的符号,
jmp
-stub

   jmp [addr]  ; FF 25 xx xx xx xx
将为第二个调用生成('因为它被认为是代码符号),用于修复两种调用之间的差异:

   call [addr] ; FF 15 xx xx xx xx
   call addr   ; E8 xx xx xx xx

因此,您的
i2
实际上将指向jmp存根的代码段地址,因此其值将是
0x???25ff

谢谢。我将查看生成的def文件,以验证它们是否正确标记了导出。这是对观察到的行为的合理解释。我个人更喜欢“根本不使用.def文件”的方法,但不幸的是,由于非技术原因,目前这不是一个选项。我将继续(这将需要一些时间)确认def是否包含
数据
注释或nt。@gwm看起来像.def生成器(在
dumpbin
输出上循环)没有使用
数据
注释导出的全局文件。所以这至少需要修正。我将看看其中涉及到什么,并对如何进行评论。@CraigRinger有什么进展吗?@qvm在澳大利亚,忙着睡觉;-)。今天应该有时间测试修补def生成器。
没有找到任何参考来确认def文件覆盖\uuu declspec注释。
-您可以尝试通过测试玩具项目来确认。我没有读过任何文章说,只是解析了编译器/链接器输出你想让别人更容易导出全局变量???让他们受苦吧!并将其作为项目指南予以取缔。替代方案太简单和优越了。@HansPassant我完全同意,但不幸的是,我目前无法改变这种做法,只能修复由此产生的错误。在这里发布了后续问题:另外,有用的文章(针对Windows特定位):@CraigRinger那么,它会是三部曲吗?或者你的问题可以被认为完全解决了?