extern “C“的作用:c语言调用c++代码中普通函数和类的方法教程(符xcode编译器演示demo)

47 篇文章 1 订阅

前言

这篇教程主要讲解了,c语言,如何调用c++的类和类方法,目的是为了用swift调用c++代码的教程做铺垫,因为swift无法直接调动c++代码,但是可以调用c语言代码和oc代码,所以先做了这个教程.作为swift调用c++代码其中一种方法的铺垫教程

extern "C"的作用

首先这个 extern “C” {}是告诉编译器,把这段代码按照C语言的格式进行编译,为啥要这样呢?因为c++有重载,而c语言没有,重载是函数名字相同,但是形参列表不同.

#ifdef __cplusplus
    extern "C"{
#endif
//这里写要C++ 的函数声明
#ifdef __cplusplus
    } //__cplusplus

先解释一下 #ifdef __cplusplus extern “C” ,这个跟#ifdef Debug语法一样,就是如果编译器是 C++ 编译器,那么执行后面的 extern “C”
上面这所有代码意思是:,如果当前编译器是按照c++编译,就把{ }中的内容按照 C语言来编译,这样一来,所有重载的方法,被按照C语言的语法变成了不同名字的方法,而不是相同名字不同参数的方法,这样就解决了C语言编译器无法处理重载的问题.

利用extern "C"给c++ 函数做声明,然后再定义函数,让.c文件可以找到c++的函数

c语言调用c++中的全局函数,这里不包含类的概念,直接用,因为是xcode平台建立的c++文件,所以.h文件扩展名变成了.hpp

//
//  CFn.hpp
//  CProductRunCppClassDemo
//
//  Created by 谭迪文 on 2021/6/26.
//

#ifndef CFn_hpp
#define CFn_hpp

#include <stdio.h>
#ifdef __cplusplus
extern "C"{
#endif
void cPrintFn1(void);//用extern "C" 声明的函数可以被 .c文件调用
void cPrintFn2(void);
#ifdef __cplusplus
} //__cplusplus
#endif

#endif /* CFn_hpp */



//
//  CFn.cpp
//  CProductRunCppClassDemo
//
//  Created by 谭迪文 on 2021/6/26.
//

#include "CFn.hpp"
#include <stdio.h>
void cPrintFn1(void){
    printf("c++文件中的全局函数cPrintFn1()运行\n");
}
void cPrintFn2(void){
    printf("c++文件中的全局函数cPrintFn2()运行\n");
}

用.c文件调用

#include <stdio.h>
#include "CFn.hpp"
#include "CppBridging.h"

int main(int argc, const char * argv[]) {
    // insert code here...
    printf("Hello, World!\n");
    cPrintFn1();
    cPrintFn2();
    return 0;
}

用c语言的.c文件调用c++ 文件中的类和类方法

##思路是把类的创建方法,写成普通的全局方法,然后再用void* 指针,来代替c++的 class 的指针

.hpp头文件

//
//  CPerson.hpp
//  externCDemo
//
//  Created by 谭迪文 on 2021/6/26.
//

#ifndef CPerson_hpp
#define CPerson_hpp

#include <stdio.h>
#include <iostream>
#endif /* CPerson_hpp */

using namespace std;
class CPerson
{
public:
CPerson();
~CPerson();
    string name;
    int age;
    void printTest(void);
private:
};

.cpp文件,注意,里面包含了一个#include "CppBridging.h"文件,里面的内容就是一个extern "C"的函数声明

//
//  CPerson.cpp
//  externCDemo
//
//  Created by 谭迪文 on 2021/6/26.
//

#include "CPerson.hpp"
#include <iostream>
#include "CppBridging.h"
using namespace::std;
CPerson::CPerson()  {
    
}

CPerson::~CPerson()  {
    
}

void CPerson::printTest(void){//创建类的方法
    cout<< "c++ 函数 printTest()运行" <<endl;
}
void* createCPerson(void){
    return new CPerson;
}
void* createCPersonBy(const char* name,int age){ //注意这里不能起名叫createCPerson(const char* name,int age)因为这个要给c语言用,c语言没有重载,会报错Conflicting types for 'createCPerson',命名冲突
    CPerson *p = new CPerson;
    p->name = name;
    p->age = age;
    return p;
}
const char* getCPersonName(void *p){
    return ((CPerson*)p)->name.data();
}

CppBridging.h头件,这个文件里面把c++的函数做了声明,因为要,之所以要单独放在一个文件当中,是因为,一会.c文件也要包含这个头文件,但是.c文件不能包含c++ 的头文件,因为c++的头文件里面声明了类 class关键字,是不能被extern "C"编译成功的.

//
//  CppBridging.h
//  externCDemo
//
//  Created by 谭迪文 on 2021/6/26.
//

#ifndef Header_h
#define Header_h

#ifdef __cplusplus
extern "C"{
#endif

void* createCPerson(void);
void* createCPersonBy(const char* name,int age);
const char* getCPersonName(void *p);
#ifdef __cplusplus
} //__cplusplus
#endif



#endif /* Header_h */

.c文件的调用

//
//  main.c
//  CProductRunCppClassDemo
//
//  Created by 谭迪文 on 2021/6/26.
//

#include <stdio.h>
#include "CFn.hpp"
#include "CppBridging.h"

int main(int argc, const char * argv[]) {
    // insert code here...
    printf("Hello, World!\n");
    void *p = createCPerson();//创建对象
    void *p2 = createCPersonBy("张三", 18);//创建对象并且赋值
    const char * name = getCPersonName(p2);//返回对象成员变量
    printf("name=%s\n",name);
    return 0;
}

demo点击我下载

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值