gpt4 book ai didi

delphi - 如何将内存流从我的应用程序传递到 DLL 或从 DLL 检索内存流?

转载 作者:行者123 更新时间:2023-12-03 15:38:52 26 4
gpt4 key购买 nike

假设我有一个 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,然后释放该内存(由调用者应用程序) ?

调用者将在每个 DLL 调用中使用动态 LoadLibrary/FreeLibrary

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

注1:调用者应用程序不知道输出大小,并假设它无法指定最大缓冲区大小。

注 2:我不确定我的 DLL 签名。如果我做错了,请原谅我。我正在寻找一种运行良好的模式(也许不仅适用于 Delphi,也适用于 C++/C# 调用者 = 对我来说是额外的好处)

最佳答案

稍微不同的方法是将每个内存流包装为 IStream,并传递生成的接口(interface)引用。因此,从 DLL 的角度来看:

uses
System.SysUtils, System.Classes, Vcl.AxCtrls;

procedure DoProcess(InStream, OutStream: TStream);
begin
//...do the actual processing here
end;

//wrapper export
procedure Process(AInStream: IStream; out AOutStream: IStream); safecall;
var
InStream, OutStream: TStream;
begin
InStream := TOleStream.Create(AInStream);
try
OutStream := TMemoryStream.Create;
try
DoProcess(InStream, OutStream);
AOutStream := TStreamAdapter.Create(OutStream, soOwned);
except
OutStream.Free;
raise;
end;
finally
InStream.Free;
end;
end;

我个人也喜欢使用 safecall,因为这是一种实现异常安全的简单方法,但我想这是一个品味问题。

编辑

上述的一个变体是让调用者提供要读取的流要写入的流:

//wrapper export
procedure Process(AInStream, AOutStream: IStream); safecall;
var
InStream, OutStream: TStream;
begin
InStream := TOleStream.Create(AInStream);
try
OutStream := TOleStream.Create(AOutStream);
try
DoProcess(InStream, OutStream);
finally
OutStream.Free;
end;
finally
InStream.Free;
end;
end;

EXE 端可能看起来像这样:

//wrapper import
type
TDLLProcessProc = procedure(AInStream, AOutStream: IStream); safecall;

procedure Process(AInStream, AOutStream: TStream);
var
InStream, OutStream: IStream;
DLLProc: TDLLProcessProc;
Module: HMODULE;
begin
InStream := TStreamAdapter.Create(AInStream, soReference);
OutStream := TStreamAdapter.Create(AOutStream, soReference);
Module := LoadLibrary(MySuperLib);
if Module = 0 then RaiseLastOSError;
try
DLLProc := GetProcAddress(Module, 'Process');
if @DLLProc = nil then RaiseLastOSError;
DLLProc(InStream, OutStream);
finally
FreeLibrary(Module);
end;
end;

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

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