在我的DLL中的Delphi中,我必须分配函数的返回pchar [英] In Delphi in my DLL do I have to allocate the return pchar of a function

查看:599
本文介绍了在我的DLL中的Delphi中,我必须分配函数的返回pchar的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个DLL,其中有一个函数返回一个pchar。 (为了避免使用borlndmm)我最初做的是将一个字符串作为pchar并返回

 结果: = pChar(SomeFuncThatReturnsString)

但是我得到了预期的结果90%的时间,其他时候我什么也不会回来



然后我想到我需要为pchar分配内存,这样做我的原始方式是将pchar指向内存,而不是总是当这个函数最初被调用时是什么。所以我现在有这个

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

但是这让我不得不在程序结束时清理分配的内存, / p>

  StrDispose(Pstr); 

所以64美元的问题是:我必须在内部的函数返回PChar时分配内存DLL或者我可以把它投给PChar?

解决方案

这个问题的典型方法是让应用程序分配内存然后将其传递给DLL来填充(甚至更好的如果DLL允许应用程序查询需要分配多少内存,因此它不必过度分配内存):

  function GetAString(Buffer:PChar; BufLen:Integer):Integer;标准
var
S:String;
begin
S:= SomeFuncThatReturnsString;
结果:= Min(BufLen,Length(S));
if(Buffer<> nil)和(Result> 0)then
Move(S [1],Buffer ^,Result * SizeOf(Char));
结束

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

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

var
S:String;
begin
SetLength(S,GetAString(nil,0));
如果Length(S)> 0然后GetAString(PChar(S),Length(S));
...
end;

var
S:数组[0..255]的Char;
Len:整数;
begin
Len:= GetAString(S,256);
...
end;

如果这不是您的选项,则需要让DLL分配内存,返回它到应用程序使用,然后DLL导出一个额外的功能,应用程序可以调用,当它完成将指针传回DLL释放:

 函数GetAString:PChar;标准
var
S:String;
begin
S:= SomeFuncThatReturnsString;
如果S - ''然后
begin
结果:= StrAlloc(Length(S)+1);
StrPCopy(Result,S);
end else
结果:= nil;
结束

程序FreeAString(AStr:PChar);标准
begin
StrDispose(AStr);
结束

var
S:PChar;
begin
S:= GetAString;
如果S - nil then
try
...
finally
FreeAString(S);
结束
结束


I have a DLL in which I have a function that returns a pchar. (as to avoid having to use borlndmm) What I was doing originally was casting a string as a pchar and returning that

Result := pChar(SomeFuncThatReturnsString)

But I was getting expected results 90% of the time and the other times I would get back nothing.

I then got to thinking that I needed to allocate the memory for the pchar and that doing it my original way was having a pchar point to memory that was not always going to be what was there when the function was called originally. So I now have this

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

But this leaves me with having to clean up the allocated memory on the programs end which I do with

StrDispose(Pstr);    

So the $64 question is: Do I have to allocate memory when returning a PChar from a function inside a DLL or can I just cast it to a PChar?

解决方案

The typical approach to this issue is to have the app allocate the memory and then pass it to the DLL to fill in (even better if the DLL allows the app to query how much memory it needs to allocate so it does not have to over-allocate memory):

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;

This allows the app to decide when and how to allocate the memory (stack versus heap, reusing memory blocks, etc):

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;

If this is not an option for you, then you need to have the DLL allocate the memory, return it to the app for use, and then have the DLL export an additional function that the app can call when it is done to pass the pointer back to the DLL for freeing:

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;

这篇关于在我的DLL中的Delphi中,我必须分配函数的返回pchar的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆