[坑]VS编译c/cpp文件,导出不同符号表
MS VisualStudio默认情况下,后缀为c的文件,使用c样式导出符号表
后缀为cpp的文件,使用c++样式导出符号表;
所以在同一个工程中:
在a.cpp中实现:
void foo() {}
在b.c中使用:
void foo();
foo(); // error LNK2019: 无法解析的外部符号 _foo
或者
在a.c中实现:
void foo() {}
在b.cpp中使用:
void foo();
foo(); // LNK2019: 无法解析的外部符号 "void __cdecl foo(void)" (?foo@@YAXXZ)
所以在cpp中使用c函数,要使用 extern “C” { void foo(); } 去包一下;
但在c中使用cpp的函数,还不知道如何引入…
1、C编译器的函数名修饰规则
__cdecl调用约定(c标准调用约定):仅在输出函数名前加上一个下划线前缀,例如_sum。
__stdcall调用约定(windows标准调用约定):编译器和链接器会在输出函数名前加上一个下划线前缀,函数名后面加上一个“@”符号和其参数的字节数,例如 _sum@number。
__fastcall调用约定(快速调用约定):在输出函数名前加上一个“@”符号,后面也是一个“@”符号和其参数的字节数,例如 @sum@number。
2、 C++编译器的函数名修饰规则
对于__stdcall方式,参数表的开始标识是“@@YG”,对于__cdecl方式则是“@@YA”,对于 __fastcall方式则是“@@YI”。
符号生成规则
_cdecl调用约定:“?”+函数名+参数表的开始标识 “@@YA” + 函数返回类型代号+参数类型代号 +结束标识“@Z”或“Z”(无参数)。
_stdcall调用约定:“?”+函数名+参数表的开始标识“@@YG”+函数返回类型代号+参数类型代号 +结束标识“@Z”或“Z”(无参数)。
_fastcal调用约定:“?”+函数名+参数表的开始标识 “@@YI”+ 函数返回类型代号+参数类型代号 +结束标识“@Z”或“Z”(无参数)。
参数表的拼写代号
X | D | E | F | H | I | J | K | M | N | _N | U | PA+ | PB+ | … |
void | char | unsignedchar | short | int | unsignedint | long | unsignedlong | float | double | bool | struct | 指针+类型 | const指针+类型 | … |
_thiscall调用约定(类成员方法的约定):“?” +函数名+ “@”字符引导的类名+参数表的开始标识(函数性质决定)+ 函数返回类型代号+参数类型代号 +结束标识“@Z”或“Z”(无参数)。
参数表的开始标识:公有(public)成员函数的标识“@@QAE”,保护(protected)成员函数的标识“@@IAE”,私有(private)成员函数“@@AAE”;如果使用Const ,则对应的标识“@@QBE”,“@@IBE”,“@@ABE”。
Post Link: [坑]VS编译c/cpp文件,导出不同符号表