C++动态库之间的参数传递

笔者做C++/C动态库也有一段时间时间了,在这里记录一下做动态库时候遇到的参数传递的坑。

一、浅谈动态库

动态库实际上应该叫做动态链接库。

在linux平台上,动态库是so后缀的文件,在windows平台上,动态库是dll后缀的文件。很多开发人员并不知道动态库是什么,但实际上动态库在软件开发中非常常见。

就拿我们在windows玩的游戏,我们会发现游戏目录下面有很多dll后缀的文件,这些文件就是动态库,有什么用呢?

比如说你游戏版本更新,如果你游戏是很多不同功能的动态库构成的,那你只需要改动到对应动态库就好了,甚至都不用更新到你的exe执行程序。简单来说,就是让你程序分很多模块解耦,更新版本时候增量更新就好。

二、动态库接口应该遵循C语言标准规则

1、接口头文件应该声明extern "C"

现在有很多开发语言,比如说java/C#/C++等,这些语言很多都支持生成动态库,那这些动态库怎样才能让不同语言调用呢。

比如现在有一个C#程序想调用一个C++编译的动态库,那就有一个规范,让C#和C++都遵循这个规范,来达到跨语言调用的目的,这个规范就是C语言标准规范。

简答来说,就是不管你用什么语言开发的动态库,提供出来的接口都应该遵循C语言的规范。

//添加extern "C" ,开始声明当前是C语言标准
#ifdef __cplusplus
extern "C" {
#endif	

int func_hello_world();

//添加extern "C" ,结束声明当前是C语言标准
#ifdef __cplusplus
}
#endif
2、接口参数中不要有string这种C++风格的参数

动态库用使用C++风格的参数是我遇到的大坑之一。

//动态库参数类型的错误用法,用std::srting作为参数类型
int func_test(std::string p_strData);

在上面这个func_test接口中,使用了std::string作为接口参数。

请问这样做可以么?

可以,但是这种写法仅仅适用于整套代码都是你独立开发,不需要其他人参与的情况。

这种写法有什么问题呢?

问题1,不是标准C风格的参数,别的语言用不了,人家C#或者java想用你C++编译的动态库,你给整了一个std::string的C++风格的参数,人家C#或者java识别不了,不兼容啊。

问题2,如果是你跟其他同事协作的情况下,虽然你们都用C++开发,但是可能他用是编译器是VS2019,你用的编译器是VC6.0。同样一个std::string处理,在不同C++编译器之间最终编译成的二进制数据是不一样的。那这样子,你同事在调用你接口时,传到你动态库里面的std::string值可能会变化,严重的话还会导致coredump崩溃问题。这里还不说你是C++11还是C++99版本的区别,不同C++版本在同一个std变量类型实现也可能会不一样的。

所以,在声明动态库接口时候,请用C语言标准的参数类型,不要用std::string/QString/std::vector等这些C++风格的参数类型。

那上面的接口应该怎么正确书写,具体如下:

//动态库参数类型的正确用法,用char这种C语言参数作为参数类型
int func_test(char* p_pcData);

在调用func_test(char* p_pcData)接口时,只需要将string内容转为char指针数组数据,通过接口传递动态库内部后,动态库内部再自行转换就好。

  • 13
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值