1. C++的编译和连接
函数同名不同参,在 c++ 是合法的
void foo(int i);
void foo(char c);
void foo(float f);
void foo(char* s);
c++ 在编译时,以上函数将被编译为类似下列符号
_foo_int
_foo_char
_foo_float
_foo_string
链接时也会去寻找是否有这样的符号
2. C的编译和链接
c 在编译时函数符号不会带上参数类型,因此以上列出函数都被编译为_foo
#include <stdio.h>
void foo(int i);
void foo(char i);
int main(int argc, char const *argv[])
{
/* code */
return 0;
}
c 编译器当发现第二个同名函数声明时,若类型不相同,则会触发类型冲突错误。
3. extern “C”
在C/C++混合项目中会看到下面的代码
#ifdef __cplusplus
extern "C" {
#endif
/*...*/
#ifdef __cplusplus
}
#endif
extern : 声明编译器遇到此变量和函数时在其他模块中寻找其定义
“C”: 表示一种符合 c 语言编译和连接的规则
因此当 c++ 编译器遇到被 extern “C” 修饰的代码时,将按照 c 语言方式编译和链接。c 不支持 “C”,这里 c++ 使用 ” __cplusplus ” 编译开关选择。
4. c 调用 c++ 代码
cpp_fun.h
/* c++ 头文件 */
#ifndef CPP_FUN_H
#define CPP_FUN_H
class MATH
{
public:
int add(int a, int b);
};
#endif /* CPP_FUN_H */
cpp_fun.cpp
/* c++ 现实库 */
#include "cpp_fun.h"
int MATH::add(int a, int b)
{
return (a + b);
}
mid.h
/* c++ 中间头文件 */
#ifndef MID_H
#define MID_H
#ifdef __cplusplus
extern "C" {
#endif
int add_cpp(int a, int b);
#ifdef __cplusplus
}
#endif
#endif /* MID_H */
mid.cpp
/* c++ 中间接口库,封装类方法 */
#include "mid.h"
#include "cpp_fun.h"
int add_cpp(int a, int b)
{
MATH math;
return math.add(a, b);
}
main.c
/* c 源码调用 c++ 方法 */
#include "stdio.h"
#include "mid.h"
int main()
{
printf("add_cpp = %d\n", add_cpp(2, 5));
return 0;
}
Makefile
all:
g++ -c cpp_fun.cpp cpp_fun.h
g++ -c mid.cpp mid.h cpp_fun.h
gcc -c main.c mid.h
gcc -o capp cpp_fun.o mid.o main.o
- rm *.o *.gch
5. c++ 调用 c 代码
c.h
/* c 头文件 */
#ifndef C_H
#define C_H
#ifdef __cplusplus
extern "C"{
#endif
void c_fun(int i);
#ifdef __cplusplus
}
#endif
#endif /* C_H */
c_fun.c
/* c 源码库 */
#include <stdio.h>
#include "c.h"
void c_fun(int i)
{
printf("c_fun: i= %d\n",i);
}
main.cpp
/* c++ 源码调用 c 函数 */
#include "c.h"
int main(int argc,char** argv)
{
c_fun(3);
return 0;
}
Makefile
all:
gcc -c c_fun.c c.h
g++ -c main.cpp c.h
g++ -o cppapp c_fun.o main.o
- rm *.o *.gch