Delphi 释放发送到外部DLL的PWideChars的位置/时间

Delphi 释放发送到外部DLL的PWideChars的位置/时间,delphi,memory-leaks,Delphi,Memory Leaks,我正在为主可执行文件上的几个PWideChar分配内存 var pwcValor: PWideChar; begin pwcValor := AllocMem( sizeof(WideChar) * Succ(Length(pValor))); StringToWideChar(pValor, pwcValor, Succ(Length(pValor))); pMetodo(pCodigo, pCodigoParametro, pwcValor); 所有这些变量都使用后期绑定发

我正在为主可执行文件上的几个PWideChar分配内存

var
  pwcValor: PWideChar;
begin
  pwcValor := AllocMem( sizeof(WideChar) * Succ(Length(pValor)));
  StringToWideChar(pValor, pwcValor, Succ(Length(pValor)));
  pMetodo(pCodigo, pCodigoParametro, pwcValor);
所有这些变量都使用后期绑定发送到外部DLL。为了避免内存泄漏,我对这种情况有一些疑问

我应该在我的exe或dll的什么地方调用这些变量的FreeMem? 我需要在这些变量上调用FreeMem吗? 我什么时候可以或者应该在这些变量上调用FreeMem? 如果我在外部DLL(也是我的)中调用它们,那么当我试图从内存卸载DLL库时,就会出现访问冲突。 Tks

编辑


有些事我忘了问。反过来呢?因此,我需要将参数从DLL返回到EXE,以便在DLL上分配pWideChar。所以,我必须在DLL上释放它们,对吗?但我可能仍然会在EXE上使用它们。在这种情况下,我必须预先分配EXE,将指针发送到DLL,并在DLL中填充指针吗?或者只是在返回参数的EXE上复制一个副本,这样我就可以在DLL上安全地释放它?

这最终取决于您使用的DLL的设计。但是,我要说的是,如果没有文档记录,那么在DLL函数返回时释放资源是安全的。我甚至建议你去做。无论如何,您必须这样做,以避免内存泄漏

关于最后一句话,DLL和调用EXE即使它们都是Delphi代码,它们使用不同的内存管理器,因此您不能在DLL中释放EXE中分配的内存。

关于释放:

这里有不同的可能解决方案:

exe可以分配缓冲区,然后由dll填充; 您的dll可以再导出一个函数,比如FreeString。Exe应该在每次处理完字符串后调用它; 您可以使用简单的宽字符串类型。这种类型的字符串使用与exe和dll相同的系统内存管理器。
就我个人而言,我建议您选择最后一个选项。

如果您有一个Delphi字符串变量,并且正在使用D2009或更高版本,以便PChar映射到PWideChar,那么您可以使用pMetodocodigo、pCodigoParameterro、PCharpValor调用您的函数。然后在DLL中,通过声明一个字符串变量并简单地分配给字符串,获取字符串的副本。例如,DLL代码如下所示:

procedure pMetodo(pwcValor: PChar);
var
  pValor: string;
begin
  pValor := pwcValor;
  ...
end;
您现有的代码非常复杂,这是不必要的。按照我建议的方式执行,可以避免使用任何显式内存分配例程。如果你想写C代码,为什么要用Delphi-


如果您想更明确,那么您可以编写PWideChar而不是PChar。

@PA,我必须保留发送到DLL的所有已分配PWideChar的指针,以便以后可以释放它们,对吗?另一个我忘了问的问题。。。反过来呢?我有一些return PWideChar,它们是在我返回到EXE的DLL上分配的。我无法在DLL中释放它们,因为EXE仍将使用它们。TksEXE代码无法释放DLL分配的内存。如果必须在DLL中alloc mem,则必须在DLL中释放它,可能是在处理返回的mem时,在EXE可调用的函数中释放。但是,我会尽量避免DLL allocs,并始终使用EXE分配的mem。有一个一般性建议,不要使用Delphi字符串类型将字符串传递给DLL。跨DLL使用宽字符串没有问题?是的,宽字符串是安全的。甚至在C++中,这种类型的字符串也存在,它被命名为BSTR.you仍然可以写pWavaCuulink字符串…避免分配