假设我有一个 TMemoryStream 我需要传递给我的 DLL 并从 DLL 取回 TMemoryStream(位图流)。

我在想我的 DLL 会有:

procedure Process(
  InBuff: Pointer;
  InBuffSize: Integer;
  var OutBuff: Pointer;
  var OutBuffSize: Integer
); stdcall;
InBuff 很简单(我认为)。我通过 TMemoryStream.MemoryTMemoryStream.Size

问题是如何在 DLL 中分配 OutBuff,调用方应用程序可以将其转换回 TMemoryStream 并稍后释放该内存(由调用方应用程序)?

调用者将使用动态 LoadLibrary/FreeLibrary 每次 DLL 调用。

我非常想要一个示例代码。希望我不要太粗鲁。

注1:调用者应用程序不知道输出大小,并假定它不能指定MAX buff大小。

注 2:我不确定我的 DLL 签名。如果我做错了,请原谅我。我正在寻找一种可以很好地工作的模式(可能不仅适用于 Delphi,还适用于 C++/C# Caller = 对我来说是奖励)

最佳答案

两个明显的选项,假设被调用者是分配内存:

1. 使用共享堆

例如,您可以使用 COM 堆。在被叫方你写:

OutBuffSize := ...; // you know what this value is
OutBuff := CoTaskMemAlloc(OutBuffSize);
// populate the buffer

调用者使用 CoTaskMemFree 销毁它。如果您愿意,可以使用 LocalAllocHeapAlloc ,这并不重要。

2. 使用被调用者的堆并导出一个解除分配器

这里使用被调用者的本地堆:
OutBuffSize := ...; // you know what this value is
GetMem(OutBuff, OutBuffSize);
// populate the buffer

您还需要导出一个解除分配器:
procedure DeallocateMemory(Ptr: Pointer); stdcall;
begin
  FreeMem(Ptr);
end;

我拒绝的另一个选择是使用共享内存管理器。我倾向于避免这种情况,因为它将调用者限制为 Delphi 程序。

要从缓冲区调用 WriteBuffer 填充流:
Stream.WriteBuffer(Buff^, BuffSize);

其中 Buff 是指向缓冲区的指针。

关于delphi - 如何从我的应用程序向/从 DLL 传递和检索内存流?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34211938/

10-10 21:23
查看更多