C++调用C接口必须要加extern "C"的原因

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

undefined reference

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

#include <stdio.h>

void cfun_output(int x)
{
    printf("%d\n", 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
时间: 2024-11-03 01:40:10

C++调用C接口必须要加extern "C"的原因的相关文章

Java调用WebService 接口 实例

这里给大家介绍一下,Java调用webservice的一个实例的过程. 本项目不能运行,因为接口地址不可用. 这里只是给大家介绍一个过程,同时留作自己的笔记.如果要学习,可以参照别人的实例.比较好. ①选择项目根目录的src ,右键,new --> webservice client 然后输入地址: http://172.18.100.52:456/hello?wsdl 必须要加wsdl结尾,这样才是一个webservice的接口. finlish.这时候刷新项目.可以看到项目下/src/com

Why? 在C++中调用被C编译后的函数,要在声明的前面加extern &quot;C&quot;

在C++程序中调用被C编译器编译后的函数,为什么要在声明的前面加extern "C"? 答:c语言不支持重载,C++支持重载 为了告诉编译器这个函数是C的编译风格,所以在找这个函数的时候也要按照C的风格去找 比如:在C++中写一个add函数 int add(int n1,  int  n2) 它找到的是?[email protected]@[email protected] ?函数名@@YA参数参数返回值@Z H代表int  M代表float @@YA表示开始      @Z表示结束

JNI之JAVA调用C++接口

1.JNI定义(来自百度百科) JNI是Java Native Interface的缩写,中文为JAVA本地调用.从Java1.1开始,Java Native Interface(JNI)标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互.JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了. 2.java通过JNI调用c++接口步骤 1).创建java包.类 此处创建 包myJNI,类TestJNI pac

java springboot调用第三方接口 借助hutoool工具类 爬坑

楼主是个后端小白一枚,之前没接触过后端,只学了java基本语法,还是在学校老师教的,学的很浅,什么ssh.ssm框架都没有学,最近在自学spring boot,看书学也看不是很懂,就在b站上看教学视频,大概看了几个老师讲的,最后选了尚硅谷的视频,老师讲的很好,有点偏向底层源码解析,讲的很细,对我这个新手小白来说也不知道好不好,反正我就是跟着看了.最近接到超哥布置的一个任务,spring boot调用第三方接口,下面就讲讲我这个新手小白是怎么一步一步磕出来结果的,顺便记录一下,免得我后面忘了. 首

javascript调用ActiveX接口失败的解决方案及使用心得

前段时间公司做了个比较大的项目,需要用到ocx控件,我厂大部分项目都采用C#.net,而winform程序条用ocx控件接口是相对简单的,但是javascript调用ocx接口,却和winform的用法有些不同,其实真捉摸下,也就能发现:差别不大. 笔者此次主要阐述在项目中用javascript调用ocx控件接口,也就是activeX控件时所遇到的问题及其解决方案.winform用法不在此篇中阐述. 调用activeX插件前,我们要做一些准备工作,我们介绍两种方案: 1.使用regsvr32 命

oc调用c++接口时 报错 Undefined symbols for architecture i386:

当在oc中调用c++中的方法时,发现说c++中的方法没定义或是找不到 Undefined symbols for architecture i386: "_desTYData", referenced from:-[TuYoo encryptParametersWithDict:] in libtuyoo.a(TuYoo.o)ld: symbol(s) not found fo 记得c++中的方法定义是要这样定义的 extern"C" { const char *d

WebApi接口 - 如何在应用中调用webapi接口

简单做个webapi(查询+添加)接口 首先,我们需要有一个webapi接口项目,我这里以前面WebApi接口 - 响应输出xml和json文章的项目来构建本篇文章的测试用例:这里新建一个 DbData 数据源类,主要用来做数据存储和提供查询列表数据及添加数据方法,具体代码如:  1 public class DbData 2     { 3         public static DbData Current 4         { 5             get 6         

远程调用内核接口的封装类(RCKObjs)

RCK 包含 Application, Function, Connection, Command, Response 和 Fields 六 大类, 其主要功能如下: a. Application 类主要负责 Function 的组织和 Response 的分发执行: b. Function    类主要负责 Function 的定义及按各模式调用: c. Connection  类主要负责登录对端应用, Command 请求执行, Response 应答管理, 以及发送和接收数据等等: d.

C# 调用微信接口的代码

调用微信接口前需要准备的内容. 1.微信公众平台的appid 2.微信公众平台的secret 3..获取tokenid 4.获取ticket 5.生成签名的随机串 6.生成签名的时间戳 7.生成签名 ================================================================================ 1.微信公众平台的appid 2.微信公众平台的secret 这两者需要登录到申请的微信公众平台中去获取,建议写在配置文件中 ======