关闭

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

标签: c++c编译链接符号表
541人阅读 评论(0) 收藏 举报
分类:

刚刚我在用试验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

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:1389次
    • 积分:45
    • 等级:
    • 排名:千里之外
    • 原创:2篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章存档