彩神大发排列五_神彩大发排列五官方 - 彩神大发排列五,神彩大发排列五官方是新浪网最重要的频道之一,24小时滚动报道国内、国际及社会新闻。每日编发新闻数以万计。

带你玩转Visual Studio——调用约定与(动态)库

  • 时间:
  • 浏览:1

进行导出接口的声明。

对你这一一二个工程进行编译,再用”dumpbin /exports ProjectName.dll”命令查看导出接口如下:

上一篇回顾:

带你玩转Visual Studio——调用约定__cdecl、__stdcall和__fastcall

这时,VisualStudio工程的默认调用约定不管是用__cdecl、__stdcall还是__fastcall,都能正常编译和运行。

【要点二】:要使编译出的动态库在不同的调用约定下都能使用,须要对所有要导出的函数使用显示的调用约定

Cdecl.h

C编译最好的土办法对函数名的修饰规则在上一章肯能讲了,再来回顾一下:

FastCall.h

当你们都都把#define EAPI extern "C" _API_中的extern "C"注释掉

为了说明你这一点,当你们都都做一二个验证。建一二个工程分别对应__cdecl、__stdcall和__fastcall,即为你这一一二个工程分别设置默认__cdecl、__stdcall和__fastcall调用约定。

error LNK2019: unresolved external symbol __imp__add@8 referenced in function _main

error LNK2019: unresolved external symbol __imp__multi@16 referenced in function _main

下一篇要讲述的内容:

带你玩转Visual Studio2——Git与Github的使用

同理,当你们都都将VisualStudio工程的默认调用约定改成__stdcall,再进行编译,会报以下一二个错误:

上一章肯能讲了,C/C++默认的调用约定是__cdecl,那都后能 修改你这一默认的调用约定呢?

答案是肯定的。假设你有一二个工程叫安VisualStudio,你想让他这一工程下的所有函数默认都使用__stdcall,右键工程->Properties->Configuration Properties->C/C++->Advanced->Calling Convention,将其设置为__stdcall即可。

用C++的最好的土办法来编译,再用命令查看函数修饰名如下:

【要点三】:要使编译出的动态库具有跨平台、跨编译器的通用性,须要使用模块文件定义导出接口(__cdecl调用约定除外)。

当你们都都都后能 看了括号中的函数修饰名(_add)、(_sub@8)、(@multi@16)遵循上述所说的规则。

其中EAPI的定义如下:

【code1】:

当你们都都用”dumpbin /exports ProjectName.dll”命令查看你这一一二个dll的导出接口:

让他看了你这一一二个名称的函数都没被更改了,这时编译出来的dll才具有跨平台、跨编译器的通用性。

上端显示使用调用约定的最好的土办法随便说说都后能 使编译出的dll在任何调用约定下都能被使用,但仅限于在相同的编译器下。

上一篇文章带你玩转Visual Studio——调用约定__cdecl、__stdcall和__fastcall中肯能讲述了__cdecl、__stdcall和__fastcall几种调用约定的主要区别。你这一章将进一步深入了解不同调用约定对编译后函数修饰名的影响,及调用约定对库函数的影响。

....

说明:

PA表示指针,上端的代号表明指针类型,肯能相类式于型的指针连续出現,以“0”代替,一二个“0”代表一次重复;如EAPI void func3(long pL, long pL2, double* pD);修饰名为:?func3@@YGXPAJ0PAN@Z

上一章提到的几种不同调用约定对编译后函数名的修饰规则,而且 而且 指C的编译最好的土办法。VS含高三种编译最好的土办法,三种是C的编译最好的土办法,三种是C++的编译最好的土办法。.c默认使用C的编译最好的土办法,而.cpp文件默认使用C++的编译最好的土办法。C和C++对函数名的修饰规则是不同的。

通过关键字extern "C" __declspec(dllexport)声明的接口函数都后能 保证__cdecl调用约定的函数名称不被改变(不被编译器加上特殊的符号进行修饰),却都后能 了保证__stdcall和__fastcall调用约定的函数不被改变。

让他发现这和当你们都都第一次查看的结果一样,但你仔细看一下第第三根结果和上端一二个有点硬不样。第第三根结果左边(add)和右边名称不一样(_add),上端两条结果左边和右边名称都相同。这是肯能:

当你们都都使用C的编译最好的土办法来编译你这一一二个工程,得到CdeclProject.dll、StdcallProject.dll、FastcallProject.dll一二个动态库,现在当你们都都都后能 在VisualStudio工程(这是生成目标为.exe的工程)中使用当你们都都:

肯能帮我使编译出的dll在不同的调用约定下都能正常使用,都后能 原本实现:

相信你一定明白缘何回事了,让他不再解释了。由此可见

肯能PA表示的是类对象的指针,则PA后接“V+类名+@@”,如

这是肯能VisualStudio工程默认是使用__cdecl约定,使用到sub和multi的以前,会去找_sub(或sub)、_multi(或multi)的函数名。但sub是__stdcall约定,编译出的StdcallProject.dll中的名称是_sub@8;而multi是__fastcall约定,编译出的FastcallProject.dll中名称是@multi@16。而且 而且 自然就找都后能 了。

在C++的编译最好的土办法中,为了能实现C++中的函数重载、继承,编译器增加了更多的修饰符号。

【要点一】:肯能一二个处理方案含高多个工程,或一二个工程中使用了多个开源库,所有工程最好使用同三种默认调用约定。

error LNK2019: unresolved external symbol __imp_@add@8 referenced in function _main

error LNK2019: unresolved external symbol __imp_@sub@8 referenced in function _main

一二个工程分别定义一二个函数如下:

一二个工程中加上入一二个函数的声明和定义

说明:你这一值默认是空,肯能默认而且 而且 __cdecl,当设置为__stdcal,表示你这一工程下的所有函数默认使用__stdcall约定,除非在函数中进行了显示声明。设置为其它值含义与此类式于。

error LNK2019: unresolved external symbol __imp__sub referenced in function _main

error LNK2019: unresolved external symbol __imp__multi referenced in function _main

编译VisualStudio,会发现报以下一二个错误:

这段代码简单解释一下,肯能定义了DYNAMIC_EXPORT宏,则_API_表示导出接口,而且 表示导入接口;而 #define EAPI extern "C" API 表示以C的最好的土办法导出(导入)接口。当你们都都在你这一一二个工程中都加入DYNAMIC_EXPORT预编译宏,表示导出接口;而在使用你这一一二个工程(库)的工程(如VisualStudio)中不加DYNAMIC_EXPORT宏,表示导入接口。

要命__stdcall和__fastcall调用约定的函数不被改变,当你们都都须要使用模块文件。为CdeclProject、FastcallProject和StdcallProject一二个工程加上模块文件,右键工程 -> Add -> New Item -> Visual C++ -> Code -> Module-Definition File(.def)

把VisualStudio工程的默认调用约定改成__fastcall,再进行编译,会报以下一二个错误:

要使编译出的动态库更有通过性,当你们都都一般会用C的最好的土办法来进行进行编译,即使用

将你这一一二个工程编译成动态库(dll),并用VS的”dumpbin /exports ProjectName.dll”命令查看你这一一二个dll的接口如下:

修饰名为:?func4@@YGHPAVNode@@PAH@Z

Stdcall.h