惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Hugging Face - Blog
Hugging Face - Blog
Microsoft Azure Blog
Microsoft Azure Blog
月光博客
月光博客
S
Securelist
J
Java Code Geeks
Recorded Future
Recorded Future
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
M
MIT News - Artificial intelligence
S
Secure Thoughts
Y
Y Combinator Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
D
Docker
Martin Fowler
Martin Fowler
The Last Watchdog
The Last Watchdog
WordPress大学
WordPress大学
The GitHub Blog
The GitHub Blog
Vercel News
Vercel News
O
OpenAI News
www.infosecurity-magazine.com
www.infosecurity-magazine.com
博客园_首页
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
PCI Perspectives
PCI Perspectives
N
News and Events Feed by Topic
H
Heimdal Security Blog
SecWiki News
SecWiki News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
博客园 - 【当耐特】
T
Troy Hunt's Blog
L
LINUX DO - 最新话题
Hacker News: Ask HN
Hacker News: Ask HN
Hacker News - Newest:
Hacker News - Newest: "LLM"
N
Netflix TechBlog - Medium
A
Arctic Wolf
The Hacker News
The Hacker News
I
Intezer
S
Schneier on Security
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Apple Machine Learning Research
Apple Machine Learning Research
L
Lohrmann on Cybersecurity
宝玉的分享
宝玉的分享
P
Privacy & Cybersecurity Law Blog
Stack Overflow Blog
Stack Overflow Blog
T
Tor Project blog
小众软件
小众软件
Simon Willison's Weblog
Simon Willison's Weblog
The Cloudflare Blog
Jina AI
Jina AI

博客园 - 泉子

算法题:求一个序列S中所有包含T的子序列(distinct sub sequence) Django模板输出Dict所有Value的效率问题 笔记:LNK2001不代表链接器真的需要链接相关符号 Windows Restart Manager 重启管理器 advapi32.dll kernel32.dll 中的两套注册表API 使用GDI+保存带Alpha通道的图像(续) 使用GDI+保存带Alpha通道的图像 窗口销毁的相关函数与消息,ActiveX控件的销毁 为什么不能将ptr_fun(operator delete)传递给For_Each 两个数之间的最短路径问题 C/C++函数中局部对象的构造与析构时机 四年记——身在中小企业 C++ Const总结 [转载]怎样用VB编写.DLL动态链接库文件 Visual Studio 6.0编译PWLib1.12总结 在Windows上编译PWLib 金山词霸没落了么? SendInput模拟键盘输入的问题 数组变量在取地址时回归:不再是指针
创建用于非Visual C++工具的DLL——VB调用C++ DLL为何必须使用def文件 - 泉子
泉子 · 2010-11-17 · via 博客园 - 泉子

在上周完成的一项工作中,发现了一个当时有点困惑的问题:

当编写供VB调用的C++ DLL时,必须使用def文件来定义导出符号,否则VB程序将链接失败。我们都知道使用def文件是为了避免C++编译器对函数进行重命名,另一个达到相同效果的替代方式是使用extern "C"标识符。若DLL由C++、C#、Java等调用,后者可以工作得很好;然而VB不可以,即便使用了extern "C"来标识导出函数,依然需要定义def文件。

就在刚刚,我找到了答案,《Windows核心编程》——19.3.2 创建用于非Visual C++工具的DLL

根据其中说明,可知:当使用__stdcall调用方式时,就算使用了extern "C",编译器也依然会更改函数名。因此会导致链接失败。

文中也提到了不依赖def文件解决此问题的一种方法。

原文如下:

如果使用Microsoft Visual C++来创建D L L和将要链接到该D L L的可执行模块,可以跳过本节内容的学习。但是,如果使用Visual C++创建D L L,而这个D L L要链接到使用任何供应商的工具创建的可执行模块,那么必须做一些额外的工作。

前面讲过当进行C和C + +混合编程时使用e x t e r n“C”修改符的问题。也讲过C + +类的问题以及为什么因为名字改变的缘故你必须使用同一个编译器供应商的工具的问题。当你直接将C语言编程用于多个工具供应商时将会出现另一个问题。这个问题是,即使你根本不使用C + +,M i c r o s o f t的C编译器也会损害C函数。当你的函数使用_ _ s t d c a l l ( W I N A P I )调用规则时会出现这种问题。这种调用规则是最流行的一种类型。当使用_ _ s t d c a l l将C函数输出时,M i c r o s o f t的编译器就会改变函数的名字,设置一个前导下划线,再加上一个@符号的前缀,后随一个数字,表示作为参数传递给函数的字节数。例如,下面的函数是作为D L L的输出节中的_ M y F u n c @ 8输出的:

__declspec(dllexport) LONG __stdcall MyFunc(int a, int b);

如果用另一个供应商的工具创建了一个可执行模块,它将设法链接到一个名叫M y F u n c的函数,该函数在M i c r o s o f t编译器已有的D L L中并不存在,因此链接将失败。

若要使用与其他编译器供应商的工具链接的M i c r o s o f t的工具创建一个可执行模块,必须告诉M i c r o s o f t的编译器输出没有经过改变的函数名。可以用两种方法来进行这项操作。第一种方法是为编程项目建立一个. d e f文件,并在该. d e f文件中加上类似下面的E X P O RT S节:

EXPORTS
MyFunc

当M i c r o s o f t的链接程序分析这个. d e f文件时,它发现_ M y F u n c @ 8和M y F u n c均被输出。由于这两个函数名是互相匹配的(除了截断的尾部外),因此链接程序使用M y F u n c的. d e f文件名来输出该函数,而根本不使用_ M y F u n c @ 8的名字来输出函数。

现在你可能认为,如果使用M i c r o s o f t的工具创建一个可执行模块,并且设法将它链接到包含未截断名字的D L L,那么链接程序的运行将会失败,因为它将试图链接到称为_ M y F u n c @ 8的函数。当然,你会高兴地了解到M i c r o s o f t的链接程序进行了正确的操作,将可执行模块链接到名字为M y F u n c的函数。

如果想避免使用. d e f文件,可以使用第二种方法输出未截断的函数版本。在D L L的源代码模块中,可以添加下面这行代码:

#pragma comment(linker, "/export:MyFunc=_MyFunc@8")

这行代码使得编译器发出一个链接程序指令,告诉链接程序,一个名叫M y F u n c的函数将被输出,其进入点与称为_ M y F u n c @ 8的函数的进入点相同。第二种方法没有第一种方法容易,因为你必须自己截断函数名,以便创建该代码行。另外,当使用第二种方法时, D L L实际上输出用于标识单个函数的两个符号,即M y F u n c和_ M y F u n c @ 8,而第一种方法只输出符号M y F u n c。第二种方法并没有给你带来更多的好处,它只是使你可以避免使用. d e f的文件而已。