C ++中extern“C”的调用约定是什么?

What is the calling convention for extern “C” in C++?

本问题已经有最佳答案,请猛点这里访问。

这个标题真的是对我要求的准确描述。

1
extern"C" int foo( int bar ) { return bar; }

从我的测试来看,它似乎不是__cdecl__stdcall__fastcall,显然不是__thiscall

公约是什么?它是如何运作的?

谢谢。


所有这extern"C"determines是名字。其他的一切都是平台相关的。

我只能认为你是测试在x86 64/win64目标吗?

如果这样,那么所有这些呼叫方会议不再存在。湖docs.microsoft.com http:///CPP /美国/建设/ x64电话会议?查看= Vs for win64 2017年。搜索"x86-64系统V)"的一切。

所有指定的呼叫尝试)会议是被忽略,和一个是统一的。

for x86平台,它又依赖什么是默认的,所以你是(曾经是)更好的开关指定的呼叫中心平台的多个会议明确的选项。


让我们看组装调试编译生成使用一个32位的Visual Studio项目(默认设置):

这里是我的计划:

1
2
3
4
5
6
7
8
9
10
11
12
extern"C" int func1(int x);
extern"C" int __stdcall func2(int x);
extern"C" int __cdecl func3(int x);

int main()
{
    int x = 0;
    func1(1);
    func2(2);
    func3(2);
    return 0;
}

func1func2func3是定义在一个单独的源文件自动内联到极限的可能性。

让我们看主组装生成的代码:

1
2
3
4
5
6
7
8
9
10
11
    func1(1);
002117E8  push        1  
002117EA  call        _func1 (0211159h)  
002117EF  add         esp,4  
    func2(2);
002117F2  push        2  
002117F4  call        _func2@4 (0211131h)  
    func3(3);
002117F9  push        3  
002117FB  call        _func3 (021107Dh)  
00211800  add         esp,4

func1 func3 for和它一样的签名。的论点是推到一个堆栈,函数调用invoked,然后堆栈寄存器(ESP)是风格派(popped)反馈到以前的地址,它是预期的_cdecl电话会议。在_ _ cdecl调用会议的来电,是负责恢复其原来的地址到堆栈指针,是由函数调用。

invocation func2学院后,没有堆栈指针调整。一个_ stdcall调用_洽会议作为它的感知。在_ _ stdcall调用汇编函数,堆栈指针是负责人反馈。inspecting大会func1学院VS func2func1结束节目,有:

1
00211881  ret    // return, no stack adjustment

而这一函数的末端组装:

1
002118E1  ret         4   // return and pop 4 bytes from stack

现在在你的结论是"无连接"属性"implies _ _ cdecl",记住这是一个Visual Studio项目的以下设置:

enter image description here

让我们换个电话会议的设置和_ _ stdcall湖看起来像这样:"组装

1
2
3
4
5
6
7
8
9
10
    func1(1);
003417E8  push        1  
003417EA  call        _func1@4 (034120Dh)  
    func2(2);
003417EF  push        2  
003417F1  call        _func2@4 (0341131h)  
    func3(3);
003417F6  push        3  
003417F8  call        _func3 (034107Dh)  
003417FD  add         esp,4

的主要论点是不是突然爆裂后,invocation of func1 -从电话会议func1认为默认的项目设置。这是技术上和你的回答。

哪里有环境__stdcall是默认的标准。例如,驱动程序的开发。


在x86的wikibook拆卸/电话会议电话会议的美国,这对于在C + +:extern"C"

Extern"C"
In a C++ source file, functions placed in an extern"C" block are guaranteed not to be mangled. This is done frequently when libraries are written in C++, and the functions need to be exported without being mangled. Even though the program is written in C++ and compiled with a C++ compiler, some of the functions might therefore not be mangled and will use one of the ordinary C calling conventions (typically CDECL).

电话会议和普通C是cdecl、stdcall和fastcall。