zoukankan      html  css  js  c++  java
  • extern “C”调用测试与验证-2016.01.06

    1 调用情形说明

    在上一篇关于extern “c”原理以及用法中,详细的说明了为什么需要extern “c”以及如何使用它解决c与c++混合编程时遇到的问题。接下来,使用示例验证方式验证c与c++函数在加入extern “c”和未加入extern “c”修饰下,函数编译以及链接时,函数命名的各种情形。主要形成如下几种情形:

    1、c函数调用c函数,不使用extern “c”修饰

    2、c函数调用c函数,使用extern “c”修饰,其实本质与1相同,因为只有c函数调用,因此不存在定义了__cplusplus的宏,extern “c”修饰不起作用

    3、c++函数调用c函数,不使用extern “c”修饰

    4、c++函数调用c函数,使用extern “c”修饰

    5、c++调用c++函数,不使用extern “c”修饰

    6、c++调用c++函数,使用extern “c”修饰

    7、c调用c++函数,不使用extern “c”修饰

    8、c调用c++函数,使用extern “c”修饰

    编译环境Visual Studio 2010,函数文件说明:c函数头文件和源文件分别命令为c.h和c.c,c++函数头文件和源文件命名为cpp.h和cpp.cpp,c调用文件命令为example.c,c++调用文件命令为example.cpp。

    1 c函数调用c函数,不使用extern “c”修饰

    文件结构视图

    image

    其中c.h文件内容

    #ifndef _c_h_
    #define _c_h_
    void c_fun();
    #endif

    c.c文件内容

    #include "c.h"
    #include <stdio.h>
    
    void c_fun()
    {
        printf("this is c function
    ");
    }

    example.c文件内容

    #include "c.h"
    
    int main()
    {
        c_fun();
        return 0;
    }

    使用dumpbin查看编译后的obj文件,c.obj符号表信息如下:

    image

    其中,c_fun编译后函数名称为_c_fun。

    example.ojb符号表信息如下:

    image

    调用链接时,main函数链接的函数名同样也是_c_fun,因此,c函数调用c函数,编译链接都使用c命名规则。

    2 c函数调用c函数,使用extern “c”修饰

    将情形1中的c.h头文件添加extern “c”修饰,具体如下:

    #ifndef _c_h_
    #define _c_h_
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    void c_fun();
    
    #ifdef __cplusplus
    }
    #endif
    #endif

    c.ojb符号表信息如下:

    image

    与情形1中c.obj符号表信息一致。因为,情形2其实本质与1相同,因为只有c函数调用,因此不存在定义了__cplusplus的宏,extern “c”修饰不起作用

    3 c++函数调用c函数,不使用extern “c”修饰

    与情形1保持所有文件内容不变,仅将调用文件example.c文件名修改成example.cpp

    image

    上述可用编译通过,但链接不通过,提示找不到如下的符号信息:

    image

    查看example.obj符号表信息:

    image

    在example.ojb符号表信息中,看到_main函数调用c_fun函数名称已经有情形1中的_c_fun变成?c_fun@@YAXXZ,而在c.obj中,c_fun函数名仍然为_c_fun,因此无法链接成功。

    4 c++函数调用c函数,使用extern “c”修饰

    在情形3基础上,在c.h头文件中,添加extern “C”修饰,告知c++编译不要使用c++编译规则编译,而是使用c编译规则。

    c.h文件具体如下:

    #ifndef _c_h_
    #define _c_h_
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    void c_fun();
    
    #ifdef __cplusplus
    }
    #endif
    #endif

    查看example.obj符号表信息:

    image

    可用看到,使用extern “c”修饰后,在_main函数中链接的符号信息为按照c编译规则命名的_c_fun,因此,可以编译链接通过。

    5 c++调用c++函数,不使用extern “c”修饰

    文件结构视图:

    image

    cpp.h头文件内容:

    #ifndef _cpp_h_
    #define _cpp_h_
    
    void cpp_fun();
    
    #endif

    cpp.cpp源文件内容:

    #include "cpp.h"
    #include <stdio.h>
    
    void cpp_fun()
    {
        printf("this is c++ function
    ");
    }

    example.cpp调用文件内容:

    #include "cpp.h"
    
    int main()
    {
        cpp_fun();
        return 0;
    }

    cpp.obj符号表信息:

    image

    example.obj符号表信息:

    image

    从上述的符号表信息可用看出,编译使用的c++的编译命名规则。

    6 c++调用c++函数,使用extern “c”修饰

    除了在cpp.h头文件中添加extern “c”修饰外,其他文件内容以及文件结构与情形5保持一致。

    cpp.h文件内容如下:

    #ifndef _cpp_h_
    #define _cpp_h_
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    void cpp_fun();
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif

    cpp.obj符号表信息:

    image

    example.obj符号表信息:

    image

    从上述符号表信息看出,使用extern “c”修饰后,编译链接使用的是c编译命名规则。

    7 c调用c++函数,不使用extern “c”修饰

    文件内容与情形5保持一致,仅将example.cpp文件名称修改成example.c,具体如下:

    image

    cpp.obj符号表信息:

    image

    example符号表信息:

    image

    在链接过程中,_main函数中链接的函数信息为_cpp_fun,而在cpp.obj符号表信息中cpp_fun函数被命名为?cpp_fun@@YAXXZ,因此出现如下的链接错误。

    image

    8 c调用c++函数,使用extern “c”修饰

    在情形7的基础上,在cpp.h头文件中添加extern “c”修饰,具体代码如下:

    #ifndef _cpp_h_
    #define _cpp_h_
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    void cpp_fun();
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif

    cpp.obj符号表信息:

    image

    example.obj符号表信息:

    image

    从上述符号表信息可以看出,编译链接均采用c编译的命名规则,因此,可以编译链接通过。

  • 相关阅读:
    第一章 简介(待续)
    第十六章 漫话网站架构师(待续)
    第十五章 网站架构师职场攻略(待续)
    第十四章 架构师领导艺术(待续)
    第十三章 大型网站典型故障分析案例(待续)
    上帝造题的七分钟2/花神游历各国/GSS4 线段树维护区间开方 By cellur925
    LuoguP1606 [USACO07FEB]荷叶塘Lilypad Pond 【最短路】By cellur925
    NOIp2013 车站分级 【拓扑排序】By cellur925
    NOI题库--盒子和小球系列 By cellur925
    关于对动态规划的思考 【转】
  • 原文地址:https://www.cnblogs.com/zhouLee/p/5104686.html
Copyright © 2011-2022 走看看