首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >"C“在C++中的作用是什么?

"C“在C++中的作用是什么?
EN

Stack Overflow用户
提问于 2009-06-24 18:10:07
回答 15查看 1.1M关注 0票数 2K

extern "C"放入C++代码到底是做什么的?

例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
extern "C" {
   void foo();
}
EN

回答 15

Stack Overflow用户

发布于 2012-10-20 17:08:32

只是想添加一些信息,因为我还没有看到它发布。

您经常会看到C头中的代码,如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#ifdef __cplusplus
extern "C" {
#endif

// all of your legacy C code here

#ifdef __cplusplus
}
#endif

这样做的目的是允许您在C++代码中使用C头文件,因为宏"__cplusplus“将被定义。但是,您还可以在遗留的C代码中使用它,其中宏没有定义,所以它不会看到唯一的C++构造。

不过,我也看到了一些C++代码,如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
extern "C" {
#include "legacy_C_header.h"
}

我想这也是同样的事情。

不知道哪条路更好,但我都看到了。

票数 415
EN

Stack Overflow用户

发布于 2015-05-29 02:06:31

g++ 反编译生成的二进制文件,以查看发生了什么

main.cpp

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void f() {}
void g();

extern "C" {
    void ef() {}
    void eg();
}

/* Prevent g and eg from being optimized away. */
void h() { g(); eg(); }

编译和反汇编生成的小精灵输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
g++ -c -std=c++11 -Wall -Wextra -pedantic -o main.o main.cpp
readelf -s main.o

产出包括:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
     8: 0000000000000000     7 FUNC    GLOBAL DEFAULT    1 _Z1fv
     9: 0000000000000007     7 FUNC    GLOBAL DEFAULT    1 ef
    10: 000000000000000e    17 FUNC    GLOBAL DEFAULT    1 _Z1hv
    11: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND _GLOBAL_OFFSET_TABLE_
    12: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND _Z1gv
    13: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND eg

Interpretation

我们看到:

  • efeg存储在代码中同名的符号中。
  • 其他的符号都被弄坏了。让我们解开它们: $ c++filt _Z1fv f() $ c++filt _Z1hv h() $ c++filt _Z1gv g()

结论:下列两种符号类型均未被破坏:

  • 已定义
  • 声明但未定义(Ndx = UND),将在另一个对象文件的链接或运行时提供

因此,在调用时需要同时使用extern "C"

  • 来自C++的C:让g++期待由gcc产生的未损坏的符号
  • C中的C++:告诉g++生成未损坏的符号供gcc使用

C中不起作用的东西

很明显,任何需要名称损坏的C++特性都不能在extern C中工作。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
extern "C" {
    // Overloading.
    // error: declaration of C function ‘void f(int)’ conflicts with
    void f();
    void f(int i);

    // Templates.
    // error: template with C linkage
    template <class C> void f(C i) { }
}

C++示例中的最小可运行C

为了更完整和更好,也请参见:如何在C++项目中使用C源文件?

从C++调用C非常容易:每个C函数只有一个可能的无损坏符号,因此不需要额外的工作。

main.cpp

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <cassert>

#include "c.h"

int main() {
    assert(f() == 1);
}

c.h

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#ifndef C_H
#define C_H

/* This ifdef allows the header to be used from both C and C++ 
 * because C does not know what this extern "C" thing is. */
#ifdef __cplusplus
extern "C" {
#endif
int f();
#ifdef __cplusplus
}
#endif

#endif

c.c

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include "c.h"

int f(void) { return 1; }

运行:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
g++ -c -o main.o -std=c++98 main.cpp
gcc -c -o c.o -std=c89 c.c
g++ -o main.out main.o c.o
./main.out

如果没有extern "C",链接将失败,原因如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
main.cpp:6: undefined reference to `f()'

因为g++希望找到一个损坏的f,这是gcc没有生产的。

GitHub上的实例

C示例中的最小可运行C++

从C调用C++有点困难:我们必须手动创建每个要公开的函数的非损坏版本。

这里,我们将演示如何向C公开C++函数重载。

main.c

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <assert.h>

#include "cpp.h"

int main(void) {
    assert(f_int(1) == 2);
    assert(f_float(1.0) == 3);
    return 0;
}

cpp.h

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#ifndef CPP_H
#define CPP_H

#ifdef __cplusplus
// C cannot see these overloaded prototypes, or else it would get confused.
int f(int i);
int f(float i);
extern "C" {
#endif
int f_int(int i);
int f_float(float i);
#ifdef __cplusplus
}
#endif

#endif

cpp.cpp

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include "cpp.h"

int f(int i) {
    return i + 1;
}

int f(float i) {
    return i + 2;
}

int f_int(int i) {
    return f(i);
}

int f_float(float i) {
    return f(i);
}

运行:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
gcc -c -o main.o -std=c89 -Wextra main.c
g++ -c -o cpp.o -std=c++98 cpp.cpp
g++ -o main.out main.o cpp.o
./main.out

如果没有extern "C",它就会失败,因为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
main.c:6: undefined reference to `f_int'
main.c:7: undefined reference to `f_float'

因为g++生成了gcc找不到的损坏符号。

GitHub上的实例

当我包含来自extern "c"的C头时,在哪里?

在Ubuntu 18.04测试。

票数 395
EN

Stack Overflow用户

发布于 2009-06-24 21:22:05

在每个C++程序中,所有非静态函数都在二进制文件中表示为符号.这些符号是特殊的文本字符串,它们唯一地标识程序中的函数。

在C中,符号名与函数名相同。这是可能的,因为在C中,没有两个非静态函数可以具有相同的名称。

因为C++允许重载,并且有许多C不具备的特性--比如类、成员函数、异常规范--所以不能简单地使用函数名作为符号名。为了解决这个问题,C++使用了所谓的名称mangling,它将函数名和所有必要的信息(比如参数的数量和大小)转换为一些只由编译器和链接器处理的奇怪的字符串。

因此,如果您指定一个函数为extern C,编译器不会对它执行名称损坏,并且可以使用它的符号名作为函数名直接访问它。

这在使用dlsym()dlopen()调用此类函数时非常方便。

票数 222
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1041866

复制
相关文章
使用jquery获取url及url参数的方法
使用jquery获取url以及使用jquery获取url参数是我们经常要用到的操作
Jensen_97
2023/07/19
1.5K0
python-获取URL中的json数据
数据源为某系统提供的URL,打开是json文件,python代码获取如下: URL替换成自己的即可。 import urllib.request def get_record(url): resp = urllib.request.urlopen(url) ele_json = json.loads(resp.read()) return ele_json if __name__ == '__main__': print(get_record('http://abc.co/
py3study
2020/01/16
5.5K0
dns url转发_获取url参数的方法
DNSPod是一款免费智能DNS产品,可以为同时有电信、网通、教育网服务器的网站提供智能的解析,让电信用户访问电信的服务器,网通的用户访问网通的服务器,教育网的用户访问教育网的服务器,达到互联互通的效果。
全栈程序员站长
2022/11/02
6.4K0
使用js获取url中的get参数并转成json格式
写在前面的 没啥说的 上代码 思路就是先获取到?后面的参数区,然后 利用字符串转数组方法获取到各个参数 var json = {}; var url = 'https://www.ba
Theone67
2019/11/21
6.3K0
js获取url参数的方法
js获取url参数的方法有很多。 1.正则分析 function getQueryString(name) { var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i"); var r = window.location.search.substr(1).match(reg); if (r != null) return unescape(r[2]); return null; } 调用方法: alert(GetQueryString("
水击三千
2018/02/27
19.7K0
封装获取url参数的方法
功能需求:前端页面来回切换需要我们去获取URL的某个参数值。这时封装一个输入参数名获取对应参数值的函数是很有必要的; //取url上的id function getQueryString(name) { //取url上的id var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i"); var r = window.location.search.substr(1).match(reg); if (r !
青梅煮码
2023/02/18
1.7K0
【API架构】使用 JSON API 的好处
在 API 工艺的世界里,没有比设计更受热议的领域了。从 REST、gRPC 到 GraphQL,有许多方法可以设计和标准化 Web API 交互。今天,我们将注意力转向另一种方法,JSON API,JSONAPI.org 上详细介绍的用于构建 API 的规范。
架构师研究会
2022/05/29
2.8K0
图片url地址的生成获取方法
在写博客插入图片时,许多时候需要提供图片的url地址。作为菜鸡的我,自然是一脸懵逼。那么什么是所谓的url地址呢?又该如何获取图片的url地址呢?
全栈程序员站长
2022/11/08
15.9K0
图片url地址的生成获取方法
封装方法,获取url地址上的参数
https://jiangsihan.cn/?id=123&name=hhh getQueryVariable(variable) { var query = window
江一铭
2022/06/17
1.4K0
封装方法,获取url地址上的参数
php – 通过curl从url获取JSON数据「建议收藏」
我试图通过curl连接从URL获取JSON数据.当我打开链接时:它显示{“version”:“N / A”,“success”:true,“status”:true}. 现在,我希望获得以上内容.
全栈程序员站长
2022/07/11
4K0
javascript/jquery获取地址栏url参数的方法
1、jquery获取url window.location.href; 2.通过javascript是如何获取url中的某个参数 function getUrlParam(name) { var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象 var r = window.location.search.substr(1).match(reg); //匹配目标参数 if (r!=null) return unes
Yiiven
2022/12/15
1.9K0
[转载]javascript/jquery获取地址栏url参数的方法
本篇文章主要是对javascript/jquery获取地址栏url参数的方法进行了介绍,需要的朋友可以过来参考下,希望对大家有所帮助
小小鱼儿小小林
2020/06/24
3.5K0
如何使用 Go 语言获取 URL?
在 Web 开发和网络爬虫等领域,经常需要获取和处理 URL(统一资源定位符)。Go 语言提供了丰富的标准库来处理 URL,使得获取和解析 URL 变得简单而高效。本文将介绍如何使用 Go 语言获取 URL 的详细步骤,并提供一些实用的示例。
网络技术联盟站
2023/07/03
7810
如何使用 Go 语言获取 URL?
WordPress 获取当前页面 URL 地址的方法
通过 WordPress 原生的函数来,或者自定义函数,都可以获取当前页面的 URL 地址。
Yangsh888
2022/03/24
1.2K0
WordPress 获取 URL 链接路径的几种方法
其实对于 WordPress 开发方面来讲使用 ID 是最为方便快捷的,但是如果在 WordPress 固定链接中也使用文章 ID 等方式来展现虽然足够简单,却也失去了更加漂亮的 URL 以及关键词优化,所以最近子凡在开发百度小程序时需要充分的使用到百度智能小程序的自然搜索功能,需要提交 URL 适配规则,那么对于网站 URL 并不是 ID 的情况来说,小程序如果使用 ID 传参,这个适配规则基本就不在一个空间了。
张子凡
2022/11/02
1.2K0
WordPress 获取 URL 链接路径的几种方法
Akismet插件获取key API的方法
作者:matrix 被围观: 2,308 次 发布时间:2011-09-25 分类:Wordpress 兼容并蓄 | 2 条评论 »
HHTjim 部落格
2022/09/26
6850
Akismet插件获取key API的方法
Python - 使用 Tinyurl API 的 URL 缩短器
在网络时代,简洁的链接对于通过社交网站、短信和其他通信方式分发超链接至关重要。但是,冗长的 URL 可能会在共享时带来挑战,并且在发送消息时可能会被截断。长 URL 通常难以记忆,并且输入起来可能非常笨拙。为了解决手头的问题,创建了诸如TinyURL之类的网址缩短平台来管理职责。Python 提供了一种方便的方法来连接这些选项。在这篇文章中,我们将编写一个Python代码来与TinyURL网站API系统互动。
很酷的站长
2023/08/11
4310
Python - 使用 Tinyurl API 的 URL 缩短器
Vue获取url网址参数的两种方法
2、如果路由中没有传参(https://w3h5.com/detail),会报错页面无法显示。正常链接应该为 https://w3h5.com/detail/234
德顺
2020/04/26
31K1
点击加载更多

相似问题

友好的配置文件URL与控制器混在一起

25

空手道摘要报告在升级到1.0.0后没有显示所有经过测试的特性

12

如何从另一个空手道特性文件中调用依赖JAR中的空手道特性?

10

黄瓜报告中称为特性/场景的空手道显示标题

10

空手道:从被调用的特性文件中处理soap响应

111
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文