假如说,我们封装的dll 有返回字符串的需求,比如有这么个函数
string oneclass::getString()
{
string res = string();
...do something,,,
return res;
}
的话,如果我们直接使用std::string 作为接口返回值的话,是会有一些问题的 具体的问题 可以百度 "尽量不要在Dll的接口中使用string作为参数" 可以了解到,这里主要列举两个可能会导致的问题.
1.由于编译器版本或者工程设置不一致,可能会出现跨模块内存分配和释放的问题,进而出现崩溃的现象,
2.配置不一致,会出现乱码的情况.
那我们确实有传递字符串的需求,那该怎么办呢?
查阅网上,汇总的资料,有以下总结:
首先肯定是要,哪个模块new出来的东西,那就要哪个模块去释放,不能跨模块释放,否则就会出问题
比如
char* oneclass::getString()
{
char* res = new char[100];
...do something,,,
return res;
}
然后 调用dll的地方 就算记得 delete了也不行总结了一下,网上的方法有以下几个:
1.返回全局变量的地址或者静态变量的地址
也就是说在dll里面搞一个全局变量,然后每次返回的时候,把返回结果赋值到全局变量里面,再将全局变量的地址返回就可以了.
但是这样子做的话,好处是不用马上去释放了,坏处就是,一直占用着内存,而且一个函数就用一个全局变量的话,函数多了就全局变量的数目就上去了,这个跟我们尽量减少全局变量或者静态变量的初衷是不一致的.此外,这个办法最严重的问题就是,无法多线程了,所以个人不推荐这个办法.
2.由调用者创建,销毁字符串
也就是 改变接口,改为这样
void oneclass::getString( char* res)
{
...do something,,,
}
然后用的时候char str[100];
getString(str);
这样子做,难就难在确定那个字符串长度上,你无法知道getString到底需要多长的字符串,定义太长浪费,太短又担心不够用,也是纠结.
3.dll 提供free方法 ,用于析构这些指针
也就是说,在dll里面new了指针,然后将其返回了,在调用的地方 用完以后,再调用dll的free方法,将指针传入,然后将其删除.这个方法倒是挺好的,这样new和delete都在dll模块了
不过我是采用了自己封装String类的方式来达到我的目的的
我封装了个string类 并将其导出.