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

来源:互联网 发布:成都程序员工资一般多少 编辑:程序博客网 时间:2024/05/20 08:25

刚刚我在用试验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"之后编译符号库中的名字就会是 "变量名",全局变量在符号库中的名字也是"变量名",此时重复了产生编译错误.
0 0