zoukankan      html  css  js  c++  java
  • extern “C”总结

    经常看到如下代码:

    #ifdef _cplusplus

    extern "C" {

    #endif

    #include "XXX.h"

    #ifdef _cplusplus

    }

    #endif

    解释:

    extern "C"的作用是,告诉C++编译器,下面的代码按照C的方式进行编译,说白了,不要对这些函数进行名字重整(function name mangling)。通常在C++程序中使用C函数或者模块时,需要用到这个功能。

    原因:

    C++为了支持函数重载,将编译后的函数名做了重整(mangled name),比如下面的函数

    int add(int a, int b) ;

    在C中编译完的名字就是add,而在C++中,编译完就变成了add_int_int(举例而已,实际因编译器而异),这样在函数名字后面加上参数的类型,就可以区分不同的重载函数了,比如还有另一个函数

    float add(float a, float b) ;

    在C++中,它会被编译成add_float_float,这就是C++区分重载函数的机制

    可是问题也随之而来

    C++进行名字重整,而C不进行重整。当C++程序引用C的函数时,它会按照重整后的名字去目标文件(.obj)中去寻找对应的函数,而目标文件中存放的却是C版本的函数,名字对不上,所以根本找不到!

    怎么办呢?

    这就是extern “C” 存在的一个原因了

    它告诉C++,包含在extern “C”{ //…}块中的东西是C版本的,你编译的时候不要进行名字重整,否则你链接的时候就无法找到我!

    于是上面的代码也就不难理解了,光说不练是扯淡,上代码

    我们简单的定义一个C头文件和实现文件,只包含一个add函数

    CClass.h 内容如下

    #ifndef __CClass_H__

    #define __CClass_H__

    extern int add(int a, int b) ;

    #endif // end __CClass_H__

    CClass.c 内容如下

    #include "CClass.h"

    int add(int a, int b)

    {

    return a + b ;

    }

    下面我们用一个C++程序来引用这个C文件

    main.cpp 内容如下

    #define _cplusplus // 为了测试,强加一句

    #ifdef _cplusplus

    extern "C" {

    #endif

    #include "CClass.h"

    #ifdef _cplusplus

    }

    #endif

    #include <iostream>

    using namespace std ;

    int main(void)

    {

    int result = add(1, 2) ;

    cout << result << endl ;

    system("pause") ;

    return 0 ;

    }

    如果没有#include <iostream>之前那些代码而只是仅仅包含

    #include "CClass.h"一句

    你就会得到下面的错误

    error LNK2019:unresolved external symbol "int __cdecl add(int,int)" (?add@@YAHHH@Z) referenced in function _main

    显然这是一个链接错误,因为找不到对应的函数定义

    当然你也可以简写成下面的形式,直接在extern “C”块中包含你想调用的函数

    extern "C"

    {

    int add(int a, int b) ;

    };

    #include <iostream>

    using namespace std ;

    int main(void)

    {

    int result = add(1, 2) ;

    cout << result << endl ;

    system("pause") ;

    return 0 ;

    }

    这在C++程序中是没有问题的,但是如果是在C程序中,则会出现编译错误,因为C中不允许extern “C”出现

    另一个需要extern “C”的场合是当C程序调用C++的东西时

    按照如下步骤做即可

    1. 在C++的.h文件中用extern “C”{}声明将被C程序使用的函数

    2. 在C++的.cpp文件中实现上面的函数

    3. 在.c文件中用extern声明要使用的C++函数

    4. 使用即可

    注意:切不可在.c文件中包含C++的.h文件,那样编译无法通过

    上代码:

    CPPClass.h中声明add函数

    #ifndef __CPPClass_H__

    #define __CPPClass_H__

    extern "C"

    {

    int add(int a, int b) ;

    };

    #endif // end __CPPClass_H__

    CPPClass.cpp实现add函数

    #include "CPPClass.h"

    int add(int a, int b)

    {

    return a + b ;

    }

    main.c 内容如下

    #include <stdio.h>

    //#include "CPPClass.h" // 不要包含头文件,否则编译不过

    extern int add(int a, int b) ; // 只需显示声明要调用的函数即可

    int main(void)

    {

    int result = add(1, 2) ; //使用函数

    printf("%d", result) ;

    return 0 ;

    }

  • 相关阅读:
    杭电 Problem
    杭电Problem 5053 the sum of cube 【数学公式】
    杭电 Problem 2089 不要62 【打表】
    杭电 Problem 4548 美素数【打表】
    杭电 Problem 2008 分拆素数和 【打表】
    杭电 Problem 1722 Cake 【gcd】
    杭电 Problem 2187 悼念512汶川大地震遇难同胞——老人是真饿了【贪心】
    杭电Problem 1872 稳定排序
    杭电 Problem 1753 大明A+B
    东北林业大 564 汉诺塔
  • 原文地址:https://www.cnblogs.com/graphics/p/1916343.html
Copyright © 2011-2022 走看看