zoukankan      html  css  js  c++  java
  • C++调用C接口必须要加extern "C"的原因

    1、第一层直接原因,如果不加extern "C",C++程序调用C接口会出现如下错误(链接时)

    undefined reference

    以实例演示:
    1)错误示例
    在ss.c中有如下代码

    #include <stdio.h>
    
    void cfun_output(int x)
    {
        printf("%d
    ", x);
    }

    在ss.h头文件中有如下定义

    #ifndef SS_H_
    #define SS_H_
    
    void cfun_output(int x);
        
    #endif // SS_H_

    在tt.cpp中调用ss.h中定义的C接口

    #include <iostream>
    
    #include "ss.h"
    
    int main()
    {
        cfun_output(5);
        
        return 0;
    }

    依次执行以下命令

    $ gcc -c ss.c -o ss.o // 只编译成目标文件,不链接
    $ g++ -c tt.cpp -o tt.o // 只编译不链接
    $ g++ -o tt tt.o ss.o // 链接生成目标程

    出现如下错误提示
    tt.o: In function `main':
    tt.cpp:(.text+0x11): undefined reference to `cfun_output(int)'
    collect2: error: ld returned 1 exit status

    2)错误纠正
    只修改ss.h为如下

    #ifndef SS_H_
    #define SS_H_
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    void cfun_output(int x);
    
    #ifdef __cplusplus
    }
    #endif
        
    #endif // SS_H_

    重新执行以下命令

    $ gcc -c ss.c -o ss.o // 只编译成目标文件,不链接
    $ g++ -c tt.cpp -o tt.o // 只编译不链接
    $ g++ -o tt tt.o ss.o // 链接生成目标程序

    运行得出结果为:5

    2、根本原因分析
    C++支持函数重载,C语言不支持函数重载。C++程序编译后在库中的名字与C语言编译后在库中的名字不同。
    假设某个函数原型为

    void foo(int x, int y)

    该函数被C编译器编译后在库中的名字为_foo,而被C++编译器编译后在库中生成的名字类似于_foo_int_int
    C++提供了C连接交换指定符号 extern "C" 用于解决名字的匹配问题。

    3、使用方法

    在被C++调用的C头文件中,将C接口包含于以下定义中

    #ifdef __cplusplus
    extern "C" {
    #endif
    
    #ifdef __cplusplus
    }
    #endif
  • 相关阅读:
    【C++基础】重载,覆盖,隐藏
    【Lintcode】003.Digit Counts
    【C++ Primer 5th】Chapter 15
    【Lintcode】120.Word Ladder
    牛客网上的题
    二叉树中和为某个值得路径
    数据库
    二叉搜索树的后序遍历序列
    从上往下打印二叉树
    二叉树的镜像
  • 原文地址:https://www.cnblogs.com/aqing1987/p/4185268.html
Copyright © 2011-2022 走看看