假设我有一个 TMemoryStream
我需要传递给我的 DLL 并从 DLL 取回 TMemoryStream
(位图流)。
我在想我的 DLL 会有:
procedure Process(
InBuff: Pointer;
InBuffSize: Integer;
var OutBuff: Pointer;
var OutBuffSize: Integer
); stdcall;
InBuff
很简单(我认为)。我通过 TMemoryStream.Memory
和 TMemoryStream.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
销毁它。如果您愿意,可以使用 LocalAlloc
或 HeapAlloc
,这并不重要。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/