研究了一下关于c/c++编译器关于导出函数的不同处理

原创 2015年07月09日 14:14:04

刚刚我在用试验ffmpeg解码库解码视频文件的时候,写好了但是提示链接错误,就网上找了一些文章,现在总结一下,如有错误或不严谨的地方请告之,免得我坑害别人,先谢过了!

总所周知,c++兼容c,但是在c++中调用纯c写的库时,编译链接目标文件的时候回提示找不到标识符,这是因为c++支持重载和多态的而c不支持的缘故.所谓重载就是函数名相同而参数个数或者参数类型不同,c++编译器在处理这个问题的时候是把函数名写成函数名+参数类型的形式,比如:int sum(int,int);c++编译器编译在符号表的名字是_sum_int_int(重载和多态其实就是编译器帮了个小忙),  而c编译器编译在符号表中的函数名是_sum;所以在C++项目中调用纯C库导出的函数时会编译链接目标文件时错误提示找不到函数,因为C编译器导出的符号不带参数类型信息,而C++编译器在链接时是按照有参数类型的名字来找函数的,所以LINK:error.

解决这个问题的方法一是在库头文件的导出函数声明前加extern "C",在C++项目中编译链接的时候,编译器会根据C的函数符号规则去找函数.
方法二不改库,在C++项目中加载头文件的#include语句用extern "C"{}的花括号包起来,这样C++编译器也会以C的规则生成函数符号去找函数进行链接.
extern "C"也不可乱用,比如你用他包住一个全局变量和一个类的声明,而类中一个成员变量和全局变量重名,普通情况下这样做是没有问题的,那是因为按照C++的编译规则会把同名成员变量在符号库中的名字是 "类名.变量名"这种形式的,而加上extern "C"之后编译符号库中的名字就会是 "变量名",全局变量在符号库中的名字也是"变量名",此时重复了产生编译错误.

北京大学 科学道德与学术规范基本知识测试 题库

【题库太大了,只试出了一部分,运气不是特别差的话通过应该没问题了吧...目测题库规模应该有300+】 1.          是以人的观念、精神、情感和价值,即以人的主观精神世界及其所沉淀的精神...
  • u013012544
  • u013012544
  • 2016年09月04日 11:04
  • 24277

数据结构课设 家谱处理 (map)

5-12 家谱处理   (30分) 人类学研究对于家族很感兴趣,于是研究人员搜集了一些家族的家谱进行研究。实验中,使用计算机处理家谱。为了实现这个目的,研究人员将家谱转换为文本文件。下面...
  • Strokess
  • Strokess
  • 2016年03月22日 22:03
  • 2024

编译器研究之路_未来50年

编译器研究之路_未来50年 今天,复杂而泛在的软件架构支撑着全球经济,编译器和高级语言正是这些软件的基石。强大而优雅的编译技术在硬件综合等领域同样有着“连城”的价值。毫不夸张地说,与半导...
  • junecauzhang
  • junecauzhang
  • 2013年07月23日 22:44
  • 1440

动态加载DLL实现不同DLL的相同导出函数调用问题

假设这样的情景:         一个exe加载了两个dll(dll1和dll2,并使用隐式加载)。dll和dll2都同时向外导出一个函数:         int add(int a, ...
  • pinganyehandan
  • pinganyehandan
  • 2012年04月16日 16:49
  • 2009

s3c2410_gpio_cfgpin等内核导出函数

1.S3C2410_GPB5是端口编号,定义在regs-gpio.h中, #define S3C2410_GPIO_BANKB   (32*1) #define S3C2410_GPIONO(...
  • chunzhilian0126
  • chunzhilian0126
  • 2017年03月31日 20:16
  • 219

s3c2410_gpio_cfgpin等内核导出函数

1.S3C2410_GPB5是端口编号,定义在regs-gpio.h中, #define S3C2410_GPIO_BANKB   (32*1) #define S3C2410_GPIONO(ba...
  • ahstusujian
  • ahstusujian
  • 2012年09月22日 15:21
  • 4310

在DLL编程中,导出函数为什么需要extern "C"

一般来讲,在DLL编程过程中,对于导出的函数前 都需要加入 extern “C”,    extern 表示这是个全局函数,可以供各个其他的函数调用;   “C” 表示编译时按照 C编译器的方式进...
  • zhongjling
  • zhongjling
  • 2012年10月19日 10:31
  • 5527

__stdcall,__cdcel,extern c 和导出函数名

无论c或c++都会对导出函数改名或不改名,无论你是静态还是动态调用一个导出函数,都可能碰上改名后导致的调用失败(甚至可能是调用约定不同而导致清理堆栈出错,造成崩溃),下面分析一下改名和调用约定之间的关...
  • cheng_xu_yuanlilin
  • cheng_xu_yuanlilin
  • 2015年11月12日 20:56
  • 456

s3c2410_gpio_cfgpin等内核导出函数

//这里面的函数都是内核导出函数/plat-s3c24XX/gpio.c中 #include #include #include #include #include #inclu...
  • lingran07
  • lingran07
  • 2012年09月21日 16:25
  • 870

Linux驱动开发中s3c2410关于gpio的内核导出函数的解读

这些函数的实现在linux内核源代码的/arch/arm/plat_s3c24xx/gpio.c中实现,这些函数的具体内容就不在这里介绍了,可以通过源代码进行查看,这里对这些函数的用法进行解读: 1....
  • u013711616
  • u013711616
  • 2015年12月15日 15:34
  • 304
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:研究了一下关于c/c++编译器关于导出函数的不同处理
举报原因:
原因补充:

(最多只允许输入30个字)