关于Delphi下PAnsiChar的使用

与C语言对应的类型为char *,意为单字节字符串指针,在Delphi下的string类型是带引用计数的,有专门的内存管理sharemm单元,在dll之间引用该单元后可以导出使用string参数的导出函数,供delphi编译的exe使用(要注意delphi版本差异)

反之,delphi实现的功能要供其它语言调用时,字符串只能使用PAnsiChar或PChar,下面仅以PAnsiChar举例(PChar类同)

一、作用域问题

返回值或可变参数为PAnsiChar时,必须申请内存(通常是被调用方申请,调用方释放)

procedure GetString(Idx: Integer; var PStr: PAnsiChar);
var
  temp: AnsiString;
begin
  temp := 'hello world!';
  if Idx = 0 then
  begin
    GetMem(PStr, Length(temp) + 1);// 多出这个1用来存\0字符串结束符
    StrPCopy(PStr, temp);// 还有个StrPLCopy,可以带长度限制
  end;
  if Idx < 0 then
    PStr := 'Not found';// 常量赋值无须申请内存和释放
  if Idx > 0 then
    PStr := PAnsiChar(temp);// 要注意了,作用域问题
end;

// 调用示例
var
  P: PAnsiChar;
begin
  GetString(0, P);//调用正常,P内容为'hello world!'
  FreeMem(P);

  GetString(-1, P);//调用正常,P内容为'Not found'
  //FreeMem(P);//不可以释放,释放可能报错

  GetString(1, P);//调用正常,P内容不确定,因为GetString过程中的temp可以已被回收
  //FreeMem(P);//不可以释放,释放可能报错
end;
  

若以DLL形式提供API,遇到PAnsiChar返回值或可变参数时,最好不要使用栈上的string进行转换,在python中调用时无法获得正确的内容,推荐在堆上申请内存GetMem,告诉调用方要记得释放(挺麻烦,尽量用常量字符串吧)。

二、回调时强制转换栈上字符串变量为PAnsiChar可以得到正确结果,要注意目标语言环境(例如在python下调用可能就不行)

三、调用方释放内存,太麻烦了

看下Windows下的API是怎么实现的?

1、使用固定长度的字符串数组首地址当字符串指针,长度是固定的,不用申请释放了

2、先使用另一个API来测试返回字符串的长度,然后调用方申请内存,传指针地址,调用完成后调用方自己释放

3、使用常量字符串

4、尽量使用整形常量,减少字符串指针在API中的使用

5、其它待补充。。。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值