加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

在我的DLL中的Delphi中,我必须分配一个函数的return pchar

发布时间:2020-12-13 22:44:01 所属栏目:Windows 来源:网络整理
导读:我有一个DLL,其中我有一个返回pchar的函数. (为了避免使用borlndmm)我最初做的是将一个字符串作为pchar转换并返回 Result := pChar(SomeFuncThatReturnsString) 但是我在90%的时间里获得了预期的结果,而其他时候我什么也得不到. 然后我开始认为我需要为pcha
我有一个DLL,其中我有一个返回pchar的函数. (为了避免使用borlndmm)我最初做的是将一个字符串作为pchar转换并返回
Result := pChar(SomeFuncThatReturnsString)

但是我在90%的时间里获得了预期的结果,而其他时候我什么也得不到.

然后我开始认为我需要为pchar分配内存,并且我原来的方式就是拥有一个pchar指向内存,这并不总是在最初调用该函数时的内容.所以我现在有这个

Result := StrAlloc(128);
Strcopy(Result,PAnsiChar(Hash(Hash(Code,1,128),2,128)));

但这让我不得不清理程序端的已分配内存

StrDispose(Pstr);

所以64美元的问题是:从DLL中的函数返回PChar时我是否必须分配内存,或者我可以将其转换为PChar?

这个问题的典型方法是让应用程序分配内存然后将其传递给DLL来填充(如果DLL允许应用程序查询需要分配多少内存,那么它就更好了,因此它不必覆盖 – 分配内存):
function GetAString(Buffer: PChar; BufLen: Integer): Integer; stdcall;
var
  S: String;
begin
  S := SomeFuncThatReturnsString;
  Result := Min(BufLen,Length(S));
  if (Buffer <> nil) and (Result > 0) then
    Move(S[1],Buffer^,Result * SizeOf(Char));
end;

这允许应用程序决定何时以及如何分配内存(堆栈与堆,重用内存块等):

var
  S: String;
begin
  SetLength(S,256);
  SetLength(S,GetAString(PChar(S),256));
  ...
end;

var
  S: String;
begin
  SetLength(S,GetAString(nil,0));
  if Length(S) > 0 then GetAString(PChar(S),Length(S));
  ...
end;

var
  S: array[0..255] of Char;
  Len: Integer;
begin
  Len := GetAString(S,256);
  ...
end;

如果这不适合您,那么您需要让DLL分配内存,将其返回给应用程序使用,然后让DLL导出一个额外的函数,当完成传递指针时应用程序可以调用该函数回到DLL中解放:

function GetAString: PChar; stdcall;
var
  S: String;
begin
  S := SomeFuncThatReturnsString;
  if S <> '' then
  begin
    Result := StrAlloc(Length(S)+1);
    StrPCopy(Result,S);
  end else
    Result := nil;
end;

procedure FreeAString(AStr: PChar); stdcall;
begin
  StrDispose(AStr);
end;

var
  S: PChar;
begin
  S := GetAString;
  if S <> nil then
  try
    ...
  finally
    FreeAString(S);
  end;
end;

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读