深入理解C/C++混合编程

 更新时间:2020年4月25日 17:46  点击:1794
在工作中,CC++密不可分,做我们嵌入式方面的,当然更多的是C,但,有时候却少不了C++,而且是CC++混搭(混合编程)在一起的,比如,RTP视频传输,live555多媒体播放等都是C++下的,他需要调用JRTPLIB库,再比如,我那邮件发送,我也用C++写的,定义了一个Email对象,包含了成员:收发邮件地址,用户名,密码等,以及方法:邮件头、Base64编码和邮件发送这些操作,很好用,所以,很多时候,C++还是蛮不错的。。。。但,*.c*.cpp文件混搭在一起,不是那么的简单,知识总是:用时方恨少啊!!!现在,我们就来慢慢的了解吧。

一、extern“C”的作用(最重点)

    1. extern "C"的真实目的是实现类CC++的混合编程extern “C”是由C++提供的一个连接交换指定符号,用于告诉C++这段代码是C函数extern “C”后面的函数不使用的C++的名字修饰,而是用C。这是因为C++编译后库中函数名会变得很长,与C生成的不一致,造成C++不能直接调用C函数。

    2.C++语言支持函数重载,C语言不支持函数重载。函数被C++编译后在库中的名字与C语言的不同。假设某个函数的原型为:void foo(int x, int y);该函数被C编译器编译后在库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字。C++提供了C连接交换指定符号extern“C”来解决名字匹配问题。

    3.extern "C"限定的函数或变量是extern类型的;externC/C++语言中表明函数和全局变量作用范围(可见性)的关键字,该关键字告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用。被extern "C"修饰的变量和函数是按照C语言方式编译和连接的。   

     4.与extern对应的关键字是static,被它修饰的全局变量和函数只能在本模块中使用。因此,一个函数或变量只可能被本模块使用时,其不可能被extern “C”修饰。

二、extern“C”__cplusplus

#ifdef __cplusplus
       extern "C" {
       #endif
       #ifdef __cplusplus
       }
       #endif
    CplusplusC plus plus"C++"用于C++文档的头文件中,上面代码的意思是:如果是C++文件(*.cpp)后缀,则使用extern “C”,在C++项目中应用的非常广泛。即使用gcc编译器编译,函数名为C类型如_foo。个人认为,搞懂了这两个关键字,尤其是理解extern "C"(再次强调,不为过,呵呵),接下来的混合编程也就差不多了,哈哈哈。。。。

三、C调用C++函数(接口)

1.设计程序,共四个文件

animal.cpp animal.h  main.c Makefile

1.1 animal.h

[root@localhost CC++]#cat animal.h
#ifndef __ANIMAL_H__  //防止被重复包含
#define __ANIMAL_H__
#ifdef __cplusplus
extern "C" {
#endif

class ANIMAL{
public:
        ANIMAL(char* );
        ~ANIMAL();
        char* getname(void);
private:
        char* name;
};
void print(void);
#ifdef __cplusplus
}
#endif
#endif  // __ANIMAL_H__

1.2 animal.cppC++文件

[root@localhost CC++]#cat animal.cpp
#include "animal.h"
#include <iostream>
using namespace std;
ANIMAL::ANIMAL(char* data)//构造函数
{       name = new char[64];
        strcpy(name, data);
}
ANIMAL::~ANIMAL() //析构函数

{
        if(name)
        {

                delete[] name;
                name = NULL;
        }
}
char* ANIMAL::getname(void)
{        return name;
}
void print(void) //对外接口,而且必须有一个非类中方法,才能被C调用
{
        ANIMAL animal("dog");
        char* animal_name = animal.getname();
        cout << "animal name is :" << animal_name << endl;
}

1.3 main.cC文件

[root@localhost CC++]#cat main.c
int main(void)

{       print();
        return 0;
}

1.4 Makefile

[root@localhost CC++]#cat Makefile
main:main.c animal.o
        gcc -lstdc++ main.c animal.o -o main

animal.o:animal.h
        g++ -c animal.cpp
.PHONY : clean
clean:
        -rm animal.o main

2.测试

2.1生成可执行程序main

[root@localhost CC++]#make
g++ -c animal.cpp
gcc -lstdc++ main.c animal.o -o main

2.2运行可执行程序main

[root@localhost CC++]# ./main
animal name is :dog

四、C++调用C函数

应该这个比较简单,我就不多写了,就直接写代码。
共有三个文件:1.h 1.c  main.cpp
[root@localhost aa]#cat 1.h
#ifndef _1__H_
#define _1__H_
extern void print(char* );
#endif

[root@localhost aa]#cat 1.c
#include <stdio.h>
#include "1.h"
void print(char* data)
{
        printf("%s\n",  data);
}
[root@localhost aa]#cat main.cpp

extern "C"{
#include "1.h"}
int main(void)
{
        print(“hello,world\n”);
        return 0;

}
gcc –c 1.c
g++ main.cpp 1.o

    接着./a.out,又可以出现我们神奇的hello,world了,C++调用C代码很简单,但C调用C++接口可把我给累坏了,苦啊。就是这个gcc后面跟的-lstdc++害的,出现undefined reference to `__gxx_personality_v0'这个错误。是因为你用gcc编译.cpp文件(animal.cpp.按系统默认.cpp文件是c++的文件格式。当然,混搭时,我还遇到了其他的一些问题,都是一些小问题,如果上面解释的还不足以让你解决C\C++混合编程的问题,可以联系我哦.

[!--infotagslink--]

相关文章

  • C++ STL标准库std::vector的使用详解

    vector是表示可以改变大小的数组的序列容器,本文主要介绍了C++STL标准库std::vector的使用详解,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2022-03-06
  • C++中取余运算的实现

    这篇文章主要介绍了C++中取余运算的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-23
  • 详解C++ string常用截取字符串方法

    这篇文章主要介绍了C++ string常用截取字符串方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-04-25
  • C++调用C#的DLL程序实现方法

    本文通过例子,讲述了C++调用C#的DLL程序的方法,作出了以下总结,下面就让我们一起来学习吧。...2020-06-25
  • c++中的system("pause")的作用和含义解析

    这篇文章主要介绍了c++中system("pause")的作用和含义,非常不错,具有参考借鉴价值,需要的朋友参考下吧...2020-04-25
  • C++中四种加密算法之AES源代码

    本篇文章主要介绍了C++中四种加密算法之AES源代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。...2020-04-25
  • 基于BootStrap Metronic开发框架经验小结【八】框架功能总体界面介绍

    这篇文章主要介绍了基于BootStrap Metronic开发框架经验小结【八】框架功能总体界面介绍 的相关资料,需要的朋友可以参考下...2016-05-14
  • C++ 整数拆分方法详解

    整数拆分,指把一个整数分解成若干个整数的和。本文重点给大家介绍C++ 整数拆分方法详解,非常不错,感兴趣的朋友一起学习吧...2020-04-25
  • C++中 Sort函数详细解析

    这篇文章主要介绍了C++中Sort函数详细解析,sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变...2022-08-18
  • C++万能库头文件在vs中的安装步骤(图文)

    这篇文章主要介绍了C++万能库头文件在vs中的安装步骤(图文),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-23
  • C# 16 进制字符串转 int的方法

    这篇文章主要介绍了C# 16 进制字符串转 int的方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下...2020-06-25
  • InterlliJ IDEA2020新建java web项目找不到Static Web的解决

    这篇文章主要介绍了InterlliJ IDEA2020新建java web项目找不到Static Web的解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-09-02
  • C#类中static变量用法分析

    这篇文章主要介绍了C#类中static变量用法,实例分析了static变量使用技巧与相关注意事项,需要的朋友可以参考下...2020-06-25
  • 详解C++ bitset用法

    这篇文章主要介绍了C++ bitset用法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-04-25
  • 浅谈C++中的string 类型占几个字节

    本篇文章小编并不是为大家讲解string类型的用法,而是讲解我个人比较好奇的问题,就是string 类型占几个字节...2020-04-25
  • C#判断一个字符串是否是数字或者含有某个数字的方法

    这篇文章主要介绍了C#判断一个字符串是否是数字或者含有某个数字的方法,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下...2020-06-25
  • C++ Eigen库计算矩阵特征值及特征向量

    这篇文章主要为大家详细介绍了C++ Eigen库计算矩阵特征值及特征向量,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-04-25
  • C# WinForm快捷键设置技巧

    这篇文章主要给大家介绍C# winform快捷键设置技巧,涉及到C winform快捷键相关知识,对C winform知识感兴趣的朋友可以参考下本篇文章...2020-06-25
  • 基于Ionic3实现选项卡切换并重新加载echarts

    这篇文章主要介绍了基于Ionic3实现选项卡切换并重新加载echarts,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-09-24
  • 详解C#切换窗口

    最近项目不多忙,于是抽点时间巩固下切换窗口问题,感兴趣的朋友跟着小编一起学习吧...2020-06-25