gpt4 book ai didi

c# - 如何释放传递给 C# 的 Delphi PByte?

转载 作者:行者123 更新时间:2023-11-30 14:05:32 25 4
gpt4 key购买 nike

我设法将 PByte 从 Delphi DLL 传递到 C# 并读取 PByte:

public void DoSomething(string company, string claimNumber, string language)
{
var buffersize = 0;
IntPtr pnt = new IntPtr();

try
{
//Get some data from Delphi dll
if (DelphiController.DoSomething(ref buffersize, ref pnt))
{
byte[] managedArray = new byte[buffersize];
Marshal.Copy(pnt, managedArray, 0, buffersize);
//Do something with managedArray...
}
}
finally
{
//how to free pnt?
DelphiController.FreeMemory(pnt, buffersize);
}
}

德尔福函数:

function DoSomething(var buffersizeArr: integer; var pnt: PByte): Wordbool; stdcall; export;
var
arrB: Tarray<Byte>;
begin
//some code
arrB := TFile.ReadAllBytes(fileName);
buffersizeArr := length(arrB);
pnt := @arrB[0];
//some more code
end;

到目前为止一切正常,所以现在我想释放 pnt 分配的内存。我试图将 pnt 传递回 Delphi DLL,但我无法释放内存并且总是得到一个 Invalid Pointer Operation 异常。

function FreeMemory(pnt: Pointer; size: integer): Wordbool; stdcall; export;
var
p: Pointer;
begin
try
FreeMem(pnt, size); //throws invalid pointer exception

result := true;
except
on e:Exception do
begin
result := false;
end;
end;
end;

那么此时释放内存的正确方法是什么?

最佳答案

Delphi 代码已损坏。您正在返回在函数返回之前被销毁的动态数组的地址。换句话说,您的 Delphi 代码返回一个指向已释放内存的指针。您的问题不应该是“我如何释放内存”,而是您应该问“我如何阻止内存被释放”!

相反,你应该这样做:

function DoSomething(var buffersizeArr: integer; var pnt: PByte): Wordbool; stdcall;
var
arrB: Tarray<Byte>;
begin
arrB := ...;
buffersizeArr := Length(arrB);
pnt := CoTaskMemAlloc(buffersizeArr);
Move(Pointer(arrB)^, pnt^, buffersizeArr);
Result := ...;
end;

然后您可以在 C# 代码中使用 Marshal.FreeCoTaskMem 释放数组。

我选择在此处使用 CoTaskMemAlloc,因为这是从共享堆分配的,因此您可以轻松地从 C# 中解除分配。您同样可以使用 LocalAlloc,然后在 C# 中使用 Marshal.FreeHGlobal 解除分配。如果您使用 GetMem 在 Delphi 中进行分配,那么您还需要导出一个 Delphi 函数来执行释放,因为 GetMem 使用内部 Delphi 堆。

一些小的注意事项:

  • export Delphi 关键字被忽略,您可以将其删除。
  • new 与您的IntPtr 一起使用是没有意义的。你可以这样写 IntPtr pnt = IntPtr.Zero
  • 如果您将 p/invoke 声明为使用 out 参数而不是 ref,那么您不需要初始化作为参数传递的变量。

关于c# - 如何释放传递给 C# 的 Delphi PByte?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57356295/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com