C/C++混合调用(链接指示)

一、C++是C的升级,为啥两者不能直接相互调用?

  1、我们知道,代码从编写,到能执行之前,仍需要经过编译(.obj)、链接阶段(.exe)。通常,编译每一个单元文件会生成目标文件,

然后链接器会把各个目标文件链接起来生成可执行性文件。

 

 

   2、链接器之所以能把目标文件相互之间链接起来,就是通过查找目标文件中的唯一函数符号(即经过编译器去编译修饰后,重新得到的函数符号)。

但是C和C++编译器对编译函数符号的生成规则是不一样的,

 

为什么C和C++编译之后的函数名会不一样?

  因为C语言只有单一的命名空间,不支持函数重载,所以不允许同名函数的存在,但是C++允许有多个命名空间,

支持函数重载,也允许同名函数的存在(通过参数类型和个数的不同进行区分

 

举个例子:C和C++对函数void GetNum()编译之后产生的函数符号

C:_GetNum()

 

C++:编译的时候会把括号内的参数也当成函数名的一部分,比如:

GetNum(int a)翻译成_GetNum_int

GetNum(int a,int b)翻译成_GetNum_int_int

 

因为编译过程中产生的函数符号不一样,在连接的时候就无法找到匹配的符号去链接,所以无法混合调用

 

二、解决办法----->关键字extern实现C/C++的混合调用

  用链接指示声明:extern "C"{/*函数名*/}告诉编译器以C的方式进行编译函数

  extern "C"的主要作用就是为了能够正确实现C++代码调用其他C语言代码。加上extern "C"后,会指示编译器这部分代码按C语言的进行编译,而不是C++的。

  注意:extern "C"只能在C++的编译环境中使用,在C环境中使用会出错

 

 

 

  举个例子有这些文件main.cpp、GetMax.c、GetMax.h

  1、在GetMax.h文件中声明该函数在C++环境下的编译方式

#ifndef _GetMax_h_
#define _GetMax_h_

//extern声明的作用是让main.cpp文件调用GetMax()这个函数的时候按照C的方式编译

#ifdef __cplusplus
extern "C" {
#endif // !__cplusplus

    int GetMax(int a,int b);

#ifdef __cplusplus
}
#endif // !__cplusplus

#endif 

 

  2、在GetMax.c文件中实现函数

#include"GetMax.h"

int GetMax(int a,int b)
{
    return a > b ? a : b;
}

   3、在main.cpp文件中调用GetMax.c中实现的方法

#include<iostream>
#include"GetMax.h"
using namespace std;
int main()
{
    int n = GetMax(1, 2);
    printf("%d\n", n); 
    system("pause");
    return 0;
}

 

 

2、在C中调用C++的函数

     第一种:.C文件调用.cpp文件中的函数

  有文件main.c、GetMax.cpp

  

  1、在GetMax.cpp中先声明当前系统编译此函数的方式为C

  

extern "C" int GetMax(int a, int b);
int GetMax(int a, int b)
{
    return a > b ? a : b;
}

  2、在main.c文件中用extern声明函数getMax()为外部函数

  

#include<stdio.h>
#include"GetMax.h"
extern int GetMax(int a, int b);
int main()
{
    int n = GetMax(1, 2);
    printf("%d\n", n);
    system("pause");
    return 0;
}

 

第二种:.C文件调用.cpp文件中的类(C中没有类的方法,所以要先把类封装成函数,在给C调用)

有文件main.c、GetMax.cpp、

1、在.cpp文件中实现类,然后封装类里面的方法

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

class TestA
{
public:
    int GetMax_(int a, int b)
    {
        return a > b ? a : b;
    }
};
int GetMax(int a, int b)
{
    TestA A;
    return A.GetMax_(a, b);
}

 

2、在.C文件中声明外部函数

#include<stdio.h>
#include"GetMaxClass.h"
extern int GetMax(int a, int b);
int main()
{
    int n = GetMax(1, 2);
    printf("%d\n", n);
    system("pause");
    return 0;
}

 

  

 

posted @ 2020-05-14 09:46  知道了呀~  阅读(604)  评论(0编辑  收藏  举报