当前位置: 首页 > news >正文

东莞建网站公司比较顺口的公司名字

东莞建网站公司,比较顺口的公司名字,淮北做网站的公司有哪些,海外永久不收费的加速器在一些c语言的library库中,我们经常可以还看下面这样的结构 #ifndef __TEST_H #define __TEST_H#ifdef _cplusplus extern "C" { #endif/*...*/#ifdef _cplusplus } #endif #endif#ifndef __TEST_H这样的宏定义应该是非常常见了,其作用是为了…

在一些c语言的library库中,我们经常可以还看下面这样的结构

#ifndef __TEST_H
#define __TEST_H#ifdef _cplusplus
extern "C" {
#endif/*...*/#ifdef _cplusplus
}
#endif
#endif

#ifndef __TEST_H这样的宏定义应该是非常常见了,其作用是为了避免重复包含。

往下看,如果定义了_cplusplus宏,则添加extern "C"的标记,那么这个标记的作用是什么呢?

#ifdef _cplusplus
extern "C" {
#endif

这里首先给出答案,这是为了c/c++程序可以相互调用。下面就看看extern "C"是如何做到的。我们分两个场景,第一个场景就是c语言写的库,c和c++程序去调用。第二个场景就是c++写的库,c和c++程序去调用。

c写的库给c/c++调用

我们看第一个例子,在这个例子中,我们使用c语言构建了一个add函数,并提供了其头文件。我们要将该实现提供给c和c++的程序调用。

下面是该例子的目录结构。

.
├── add.c
├── add.h
├── main_c.c
├── main_cpp.cpp
└── makefile

add.h

#ifndef C_EXAMPLE_H
#define C_EXAMPLE_H#ifdef __cplusplus
extern "C"{
#endifextern int add(int x,int y);#ifdef __cplusplus
}
#endif#endif

add.c

#include "add.h"
int add( int x, int y )
{return x + y;
}

main_cpp.cpp

#include "add.h"int main()
{add(2,3);return 0;
}

main_c.c

#include "add.h"int main()
{add(2,3);return 0;
}

makefile

all:main_cpp main_cmain_cpp: main_cpp.o add.o$(CXX)  -o $@ $^main_c: main_c.o add.o$(CC) -o $@ $^main.o: main_cpp.cpp$(CXX) -c -o $@ $<add.o: add.c$(CC)  -c -o $@ $<clean:rm -f *.o main_cpp main_c

使用make命令对上述模块进行构建。如果没有任何错误,那么恭喜你,add.o成功的被c和c++程序使用了。

我们知道c和c++编译器编译出来的符号名称是不同的,用c++的方式去寻找c语言的符号是无法寻找到的。extern "C"为何可以做到?

我们使用readelf -s add.o查看add.o的符号,可以看到add函数的名称就是add,这个就是典型c编译器编译出来的名字。

Symbol table '.symtab' contains 9 entries:Num:    Value          Size Type    Bind   Vis      Ndx Name0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS add.c2: 0000000000000000     0 SECTION LOCAL  DEFAULT    13: 0000000000000000     0 SECTION LOCAL  DEFAULT    24: 0000000000000000     0 SECTION LOCAL  DEFAULT    35: 0000000000000000     0 SECTION LOCAL  DEFAULT    56: 0000000000000000     0 SECTION LOCAL  DEFAULT    67: 0000000000000000     0 SECTION LOCAL  DEFAULT    48: 0000000000000000    20 FUNC    GLOBAL DEFAULT    1 add

我们再次查看readelf -s main_cpp.o | grep add去查看一下main_cpp中的符号表:

   72: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS add.c90: 0000000000400570    20 FUNC    GLOBAL DEFAULT   11 add

可以看到main_cpp中的符号表的名字也是add,因此main_cpp成功的找到了add函数。

但是我们知道c++的编译器在生成符号时,通常都会带上符号的参数类型(因为c++支持重载),例如下面的c++程序,编译之后,我们使用readelf查看符号表。

int add( int x, int y )
{return x + y;
}int main()
{add(2,3);return 0;
}

其输出的结果如下所示:

86: 0000000000400556    20 FUNC    GLOBAL DEFAULT   11 _Z3addii

可以看到add生成符号是_Z3addii。

因此,加与不加extern "C",add函数生成的符号名称是不同的。

看到这里,聪明的你已经大概知道extern "C"的作用了,就是修改了符号表的生成方式,将c++符号的生成方式换成了c的生成方式。

c库中生成的符号是c编译器的符号, 因此c语言可以直接链接。而c++程序需要使用extern "C"让编译器使用c的符号命名方式去进行链接,这样才能找到对应的符号。

c++写的库给c/c++调用

下面这个例子,我们使用c++语言构建了一个add函数,并提供了其头文件。我们要将该实现提供给c和c++的程序调用。

.
├── add.cpp
├── add.h
├── main_c.c
├── main_cpp.cpp
└── makefile

add.h

#ifndef C_EXAMPLE_H
#define C_EXAMPLE_H#ifdef __cplusplus
extern "C"{
#endifextern int add(int x,int y);#ifdef __cplusplus
}
#endif#endif

add.cpp

#include "add.h"
int add( int x, int y )
{return x + y;
}

main_cpp.cpp

#include "add.h"int main()
{add(2,3);return 0;
}

main_c.c

#include "add.h"int main()
{add(2,3);return 0;
}

makefile

all:main_cpp main_cmain_cpp: main_cpp.o add.o$(CXX)  -o $@ $^main_c: main_c.o add.o$(CC) -o $@ $^main.o: main_cpp.cpp$(CXX) -c -o $@ $<add.o: add.cpp$(CXX)  -c -o $@ $<clean:rm -f *.o main_cpp main_c

其实这种场景和第一种场景是基本一致的。现在我们的库add.o是使用c++编译器生成的。

我们使用readelf查看其内容,可以看到其内容和之前c语言生成的库,add函数的符号是一样的。因为我们此时编译时使用了extern "C",也就是说使用c语言的符号构建方式进行编译。

Symbol table '.symtab' contains 9 entries:Num:    Value          Size Type    Bind   Vis      Ndx Name0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS add.c2: 0000000000000000     0 SECTION LOCAL  DEFAULT    13: 0000000000000000     0 SECTION LOCAL  DEFAULT    24: 0000000000000000     0 SECTION LOCAL  DEFAULT    35: 0000000000000000     0 SECTION LOCAL  DEFAULT    56: 0000000000000000     0 SECTION LOCAL  DEFAULT    67: 0000000000000000     0 SECTION LOCAL  DEFAULT    48: 0000000000000000    20 FUNC    GLOBAL DEFAULT    1 add

接下来链接的过程就和第一个场景一样了。

在本场景中,使用c++编写了一个包含add函数的模块,对其编译时,使用了c语言的符号构建方式。因此其符号表和c语言的库是相同的。最终链接时,由于加上了extern "C", 链接过程也将使用c语言的方式去寻找符号。

总结

  • extern "C"实际上就是告诉c++编译器去使用c编译器的规则去进行构建。
  • 在日常使用中,c++调用c库的使用频率更高一些,案例一就是这样的例子。
http://www.yayakq.cn/news/325846/

相关文章:

  • sql server网站建设手机网站建设推广软文
  • 社区类网站建设的例子如何做专业网站的线下推广
  • 免费做网站有哪些建立网站 用英语
  • 外贸网站系统设计网页的8个步骤
  • 贴吧网站建设高端网约车
  • 在哪下载免费的英文版网站模板公司注册地址变更需要什么资料
  • 手机端的网站首页该怎么做免费广告行业网站建设
  • 建设网站需要什么条件环保网站可以做哪些内容
  • 长沙网站关键词开发小程序多少钱一个
  • 网站建设有哪些工作需需要筹备电子邮箱免费注册
  • 各大网站什么时候恢复彩色seo搜外
  • 潍坊网站排名提升重庆网站建设重庆网站制作
  • 大连做网站外包北京注册公司需要什么手续和证件
  • 郑州免费建站哈尔滨最新信息
  • php做的网站有哪些网页设计实验报告步骤
  • 怎么维护好网站官网推广方案seo
  • wordpress本地站点地址如何配置南京制作网页速成班
  • 网站开发项目背景六安做网站的公司
  • 做网站服务器租一年多少钱全球设计中心
  • 深圳工信部网站备案网站免费建
  • 大连网络建站模板做网站程序员都要先做维护么
  • 外发加工网订货会班级优化大师免费下载
  • 运营好网站网页设计试题及答案
  • 菏泽企业网站建设网站建设的方式
  • 各大网站平台发布信息网页设计注册页面代码
  • 包装网站模板798艺术区个人拍照图片及价格
  • 宁波派桑网站建设wordpress istyle2
  • 做网站要学点什么建设银行网站证书
  • 珠海市网站建设开发公司百度搜索量怎么查
  • wordpress分类 菜单如何做网站优化关键词优化