• 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); 
        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);
        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);
        system("pause");
        return 0;
    }

      

  • 相关阅读:
    一款简单易用的.Net 断言测试框架 : Shouldly
    单元测试 使用 Effort 内存数据库 报错
    解决 对路径bin oslyn..的访问被拒绝
    数据库设计:多选查询与匹配
    oracle快速创建主键
    models中,字段参数limit_choices_to的用法
    models中,对于(Small)IntegerField类型字段的choices参数在前端的展示
    Django ModelForm组件
    会议室预定
    Django admin管理工具
  • 原文地址:https://www.cnblogs.com/-citywall123/p/12885945.html
Copyright © 2020-2023  润新知