DLL PChar 参数如何转换成 String

iamduo 2013-01-17 04:30:11
在写DLL的时候,我们都知道,参数不能用 String,而用PChar替代。
我这里有一点不明白,
如果这个字符串不是立即就会处理,需要攒起来的,那么该如何转换呢?
(也许 New 一个 PChar,Move 一下内容也是一种不错的方法。这里不考虑这种方案。)

由于,很多情况下,我的设计都类似。
1. DLL 中创建一个全局的对象 A,处理这些字符串。
2. 不导出类,而仅仅是一个方法,参数用 PChar。该方法的实现中,用 A 的方法来执行。
3. PChar 用 StrPas 转换成 String 给 A 的方法。(!!!这里我总是在怀疑)
最近我总碰到莫名的地址报错。我更加怀疑这个地方了。

有没有同行研究过这种情况?
大家都是怎么处理的呢?

假设:有个主程序 B.exe。 写日志的类写在 C.dll 中,并且导出一个函数 Log(AStr:PChar)。有个子模块 D.dll 处理一些简单业务。
C.dll 在 exe 创建的时候就被动态加载。当 B 调用 D 之前,写一下日志,D在处理的时候,写一下日志,B调用完成后写一下日志。
“写日志”由于不是立即执行的,我们可以简单解释成 GetMem 分配内存。
那么,在 Log 这个函数里,每一次 GetMem 是不是都能由 C.dll 在被释放的时候,自己负责释放呢?
...全文
225 13 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
simonhehe 2013-01-17
  • 打赏
  • 举报
回复
引用 楼主 iamduo 的回复:
在写DLL的时候,我们都知道,参数不能用 String,而用PChar替代。 我这里有一点不明白, 如果这个字符串不是立即就会处理,需要攒起来的,那么该如何转换呢? (也许 New 一个 PChar,Move 一下内容也是一种不错的方法。这里不考虑这种方案。) 由于,很多情况下,我的设计都类似。 1. DLL 中创建一个全局的对象 A,处理这些字符串。 2……
StrPas函数不会出错, 你看下异常发生时传入的Pchar值是什么东东, 估计是被释了
function StrPas(const Str: PAnsiChar): AnsiString;
begin
  Result := Str;
end;
蓝色光芒 2013-01-17
  • 打赏
  • 举报
回复
StrPas函数,其实就是直接把 aStr := aPChar; 这样使用没问题,字符串的内存也是自动释放的。 内存错误可以跟踪得到的,把错误提示发上来
CCDDzclxy 2013-01-17
  • 打赏
  • 举报
回复
引用 7 楼 iamduo 的回复:
其实,我就是想问的,怎么把 PChar 转成 String ? 直接用 StrPas 赋值,这样做法靠谱吗?
我测试了下

var pc :PChar;
    str :string;
begin
  pc := 'AAA';
  Memo1.Lines.Add('pc : '+inttostr(integer(@pc[0]))+' , '+pc);

  str := pc;
  Memo1.Lines.Add('str : '+inttostr(integer(@str[1]))+' , '+str);

  str := StrPas(pc);
  Memo1.Lines.Add('str : '+inttostr(integer(@str[1]))+' , '+str);
end;
输出:

pc : 4623508 , AAA
str : 14305844 , AAA
str : 14321380 , AAA
看到 StrPas 应该是 重新分配地址的,应该是 靠谱的吧~~
xhz8000 2013-01-17
  • 打赏
  • 举报
回复
其实分配内存有谁发起都行的!记得是谁申请就由谁来释放。 比如你由DLL申请内存,由DLL来释放!
xhz8000 2013-01-17
  • 打赏
  • 举报
回复
不转都可以啦
iamduo 2013-01-17
  • 打赏
  • 举报
回复
引用 5 楼 CCDDzclxy 的回复:
exe 和 dll 都是 同版本delphi做的 的话,是否可以直接传 string?
可以,所有程序的 dpr 里,第一个就 Use ShareMM。是可以传 string 的。 不过,不建议这么做。 使用面太狭窄了,而且多发布东西,不能给其他语言使用。
iamduo 2013-01-17
  • 打赏
  • 举报
回复
引用 2 楼 xhz8000 的回复:
参数不能用 String,而用PChar替代。 记住只是参数不能用String;但在动态库里面是可以用String的
其实,我就是想问的,怎么把 PChar 转成 String ? 直接用 StrPas 赋值,这样做法靠谱吗?
iamduo 2013-01-17
  • 打赏
  • 举报
回复
引用 1 楼 kiboisme 的回复:
3. PChar 用 StrPas 转换成 String 给 A 的方法 在 Log 这个函数里,每一次 GetMem 是不是都能由 C.dll 在被释放的时候,自己负责释放呢? 何来的GetMem?
这么快就有那么多回复了,不错不错!!! 不好意思,这个是我没有说清楚。 这里是我的第四个问题,我想问的意思是,每次调用 Log 函数,都会分配一次内存,但是我不是很清楚,这个分配内存的动作是由谁发起的,B.exe ? C.dll ? D.dll ? 如果全都由 C.dll 释放会不会安全。
CCDDzclxy 2013-01-17
  • 打赏
  • 举报
回复
exe 和 dll 都是 同版本delphi做的 的话,是否可以直接传 string?
xhz8000 2013-01-17
  • 打赏
  • 举报
回复
我说的是在d7版本之前的!
xhz8000 2013-01-17
  • 打赏
  • 举报
回复
在我用delphi做这么久的DLL来看,就是觉得传入unicode不好处理!
xhz8000 2013-01-17
  • 打赏
  • 举报
回复
参数不能用 String,而用PChar替代。 记住只是参数不能用String;但在动态库里面是可以用String的
蓝色光芒 2013-01-17
  • 打赏
  • 举报
回复
3. PChar 用 StrPas 转换成 String 给 A 的方法 在 Log 这个函数里,每一次 GetMem 是不是都能由 C.dll 在被释放的时候,自己负责释放呢? 何来的GetMem?

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧