IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> c++/c混合编程 -> 正文阅读

[C++知识库]c++/c混合编程

一、前言

????????代码从编写到能执行之前,需要经过编译、链接阶段。通常,编译每一个单元文件会生成目标文件,然后链接器会把各个目标文件链接起来生成可执行性文件。链接器之所以能把目标文件相互之间链接起来,就是通过查找目标文件中的唯一函数符号(即经过编译器去编译修饰后,重新得到的函数符号)。

????????C和C++编译器对编译函数符号的生成规则是不一样的,例如对于函数void fun(int a, int b),C经过编译后生成的符号为_fun, C链接器链接的时候就会去找_fun这样的函数符号;在C++中,生成的类似为_fun_int_int, 新生成的符号名不仅带有函数名,还有参数类型。正因为他们两者编译函数的时候,生成的符号规则不一样,所以,在混合编程中,如果我们不进行任何处理,而相互效用的话,必然会出现在链接的时候,找不到符号链接的情况。

ps : c++符号名称的规则,并没有一种唯一的命名规范, 不同的编译器命名规范不同, 但是思路一致! 如下图所示 :

????????为什么编译器在设计的时候要这么设计生成的符号呢?

????????因为C只有单一的命名空间,不支持函数重载之类的特性

????????C++为了支持函数重载(即函数名字可以相同,参数类型或个数不同),允许存在同名的函数;且C++甚至可以存在相同的类型、变量等,因为在C++中命名空间的存在。

二、extern "C"

extern "C"的真实目的是实现类C和C++的混合编程。

在C++调用C的时候, 告诉C++编译器, 编译的时候,不要用默认的C++规范查找, 而要采用C规范去查找。

在C调用C++的时候, 告诉C++编译器, 编译的时候, 不要按照C++默认的规范去编译, 而应该按照C规范去编译。

三、c++引用c

1、简单示例

// 注意: 该代码是C程序, 请放在.c文件中, 这样确保是C编译器
 
#include <stdio.h>
 
void fun()
{
	printf("ok\n");
}
// 注意: 该代码是C++程序, 请放在.cpp文件中, 这样确保是C++编译器
 
#include <iostream.h>
 
extern "C" void fun(); // 暂时骗过编译器, 并对链接器说, 你要按照C规范链接, 去找_fun, 而不是"?fun@@YAXXZ"
 
int main()
{
	fun();
 
	return 0;
}

2、代码优化:

既然#include相当于文本拷贝, 那为何不把extern "C" 语句放到头文件中呢?
但是我很遗憾的告诉大家, 如果你这样做的话, 那么C文件就不能调用C文件的方法了!因为C的编译器不支持 extern "C" 语法!这里要引出一个宏, __cplusplus, 只要是C++文件, 编译器就会自动定义一个这样的宏, 我们就能利用这个宏做到C/C++的终极混编了!

// --------------cfun.h
#ifndef __C_FUN_H__
#define __C_FUN_H__
 
#ifdef __cplusplus
extern "C"{
#endif // __cplusplus
 
	void cfun();
#ifdef __cplusplus
}
#endif
 
 
#endif
// --------------cfun.c
#include "cfun.h"
#include <stdio.h>
 
void cfun()
{
	printf("hello world.\n");
}
// --------------main.cpp
#include <iostream>
#include "cfun.h"

int main()
{
	cfun();
	system("pause");
	return 0;
}

四、c引用c++

核心就是告诉C++编译器, 编译的时候, 不要按照C++默认的规范去编译, 而应该按照C规范去编译。其次,要实际谨记,include就是原地展开,这样就容易理解了!

方式1、函数在cpp文件中定义的时候使用extern "C"修饰

// cal.cpp 

extern "C" int sum(int a, int b)
{
    return a + b;
}
// hyber_test.c 

#include <stdio.h>
extern int sum(int a, int b);

int main()
{
    printf("sum:%d\n", sum(1,2));
}

?

方式2、在cpp头文件声明的时候使用extern "C"修饰

在cpp文件中用下列方式定义函数:

returnType FunName(parameters list).

然后在相应的头文件中进行声明:

extern "C"?returnType FunName(parameters list);

在相应的.c文件中添加函数声明(extern returnType FunName(parameters list);),然后直接利用相应的函数即可.

cal.h:

#ifndef CAL_HEADER
#define CAL_HEADER

extern "C" int sum(int a, int b);

#endif CAL_HEADER

cal.cpp:

// cal.cpp 

#include <cal.h>

int sum(int a, int b)
{
    return a + b;
}

在C的代码文件main.c中调用print函数:

// hyber_test.c 

#include <stdio.h>
extern int sum(int a, int b);
int main()
{
    printf("sum:%d\n", sum(1,2));
}

note:

在C的代码文件中直接#include "cal.h"头文件,编译出错。

而且如果不加extern int sum(int a, int b);编译也会出错。

ref:

再谈谈只针对C++编译器/链接器的extern “C“------C与C++的相互调用_涛歌依旧的博客-CSDN博客

遇到问题 --- C++调用C静态库,出现undefined reference的问题 - 蜗牛的博客 | VK's Blog

C++程序中出现undefined reference to ......_阿卡基YUAN的博客-CSDN博客_undefinedreferenceto是什么意思

C和C++混合编译,extern和extern "C" - 云+社区 - 腾讯云

C/C++混合编程_embed_huang的博客-CSDN博客_c c++混合编程

浅谈C/C+混合编程 - 知乎

c/c++实现混合编程 - heity - 博客园

【重新认识C++】08-extern C2-C、C++混合开发_哔哩哔哩_bilibili

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-06 15:59:31  更:2022-04-06 16:01:17 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 0:30:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码