InBuff ( ). TMemoryStream.Memory TMemoryStream.Size.
.
, OutBuff DLL, - TMemoryStream ( )?
DLL, , DLL. . Process() , , , Process(), . , . :
procedure Process(InBuff: Pointer; InBuffSize: Integer; OutBuff: Pointer; var OutBuffSize: Integer); stdcall;
begin
//...
if (OutBuf <> nil) then
begin
// copy no more than OutBuffSize bytes into OutBuf, and then
// update OutBuffSize with the number of bytes actually copied...
Move(..., OutBuf^, ...);
OutBuffSize := ...;
end else begin
// update OutBuffSize with the number of bytes needed for OutBuff...
OutBuffSize := ...;
end;
//...
end;
var
InStream: TMemoryStream;
OutStream: TMemoryStream;
BuffSize: Integer;
begin
InStream := TMemoryStream.Create;
try
// fill InStream as needed...
BuffSize := 0;
Process(InStream.Memory, InStream.Size, nil, BuffSize);
OutStream := TMemoryStream.Create;
try
OutStream.Size := BuffSize;
Process(InStream.Memory, InStream.Size, OutStream.Memory, BuffSize);
// use OutStream as needed...
finally
OutStream.Free;
end;
finally
InStream.Free;
end;
end;
If you really want the DLL to allocate memory, you need to change the signature of your DLL function to OutBuffbe a parameter var. You must also export an additional function so that the DLL can free the memory allocated by the DLL. The advantage of this approach is that the caller would only need to be called once Process(), and the DLL can decide how he wants to allocate and free memory. For example:
procedure Process(InBuff: Pointer; InBuffSize: Integer; var OutBuff: Pointer; var OutBuffSize: Integer); stdcall;
begin
//...
OutBuffSize := ...;
GetMem(OutBuf, OutBuffSize);
Move(..., OutBuf^, OutBuffSize);
//...
end;
procedure FreeProcessBuff(InBuff: Pointer); stdcall;
begin
FreeMem(InBuff);
end;
type
TMemoryBufferStream = class(TCustomMemoryStream)
public
constructor Create(APtr: Pointer; ASize: NativeInt);
end;
procedure TMemoryBufferStream.Create(APtr: Pointer; ASize: NativeInt);
begin
inherited Create;
SetPointer(APtr, ASize);
end;
...
var
InStream: TMemoryStream;
OutStream: TMemoryBufferStream;
Buff: Pointer;
BuffSize: Integer;
begin
InStream := TMemoryStream.Create;
try
// fill InStream as needed...
Buff := nil;
BuffSize := 0;
Process(InStream.Memory, InStream.Size, Buff, BuffSize);
try
OutStream := TMemoryBufferStream.Create(Buff, BuffSize);
try
// use OutStream as needed...
finally
OutStream.Free;
end;
finally
FreeProcessBuff(Buff);
end;
finally
InStream.Free;
end;
end;