我正在尝试为Delphi 2007中的项目制作一个使用XE7中的TAmazonStorageService组件的dll。
但是,我遇到了几次内存泄漏,或者数组的所有索引都返回了最后一个字符串。
这是我的功能:
function ListBuckets(const PrivateKEY: PAnsiChar; const PublicKEY: PAnsiChar;
out ArrayBuckets: TArray<PAnsiChar>;
out Error: PAnsiChar): Boolean; stdcall;
var
AmazonConn: TAmazonConnectionInfo;
AmazonS3: TAmazonStorageService;
ResponseInfo: TCloudResponseInfo;
BucketsList: TStrings;
I: Integer;
begin
Result := True;
AmazonConn := TAmazonConnectionInfo.Create(nil);
AmazonConn.AccountName := string(PublicKEY); { AccessKeyID }
AmazonConn.AccountKey := string(PrivateKEY); { SecretAccessKeyID }
AmazonS3 := TAmazonStorageService.Create(AmazonConn);
ResponseInfo := TCloudResponseInfo.Create;
Error := '';
try
BucketsList := AmazonS3.ListBuckets(ResponseInfo);
if not Assigned(BucketsList) then
begin
Result := False;
Error := PAnsiChar(AnsiString(ResponseInfo.StatusMessage));
end
else
begin
SetLength(ArrayBuckets, BucketsList.Count);
for I := 0 to BucketsList.Count - 1 do
ArrayBuckets[I] := PAnsiChar(AnsiString(BucketsList.Strings[I]));
end;
finally
BucketsList.Free;
ResponseInfo.Free;
AmazonS3.Free;
AmazonConn.Free;
end;
end;
exports ListBuckets;
这是即时消息“尝试”使用此功能的方式。需要在Delphi XE7和Delphi 2007中工作。
type
TAnsiCharArray = array of PAnsiChar;
function ListBuckets(const PrivateKEY: PAnsiChar; const PublicKEY: PAnsiChar;
out ArrayBuckets: TAnsiCharArray;
out MensagemErro: PAnsiChar): Boolean; stdcall;
external 'Test.dll';
function ListBucketsDelphi(const PrivateKEY: string; const PublicKEY: string;
out StringListBuckets: TStringList;
out Error: string): Boolean;
var
vAnsiPrivateKEY: PAnsiChar;
vAnsiPublicKEY: PAnsiChar;
vAnsiError: PAnsiChar;
vStringArray: TAnsiCharArray;
I: Integer;
begin
{$IFDEF UNICODE}
vAnsiPrivateKEY := PAnsiChar(RawByteString(PrivateKEY));
vAnsiPublicKEY := PAnsiChar(RawByteString(PublicKEY));
{$ELSE}
vAnsiPrivateKEY := PAnsiChar(PrivateKEY);
vAnsiPublicKEY := PAnsiChar(PublicKEY);
{$ENDIF}
//StringListBuckets need to be created before...
Result := ListBuckets(vAnsiPrivateKEY, vAnsiPublicKEY, vStringArray, vAnsiMensagemErro);
if not (Result) then
Error := string(vAnsiError);
try
if Result then
begin
for I := Low(vStringArray) to High(vStringArray) do
StringListBckets.Append(vStringArray[I]);
end;
except
Result := False;
Error := '"StringListBuckets" not created.';
end;
end;
我搜索了一下,但未发现有关在unicode dll中返回数组的任何信息,或者我搜索错误。
有人可以帮忙吗?
提前致谢。
完全不能安全地调用该函数。您有以下问题:
out
该函数返回时无效的字符串的指针(您的两个参数)。换句话说,一旦函数返回,这些指针指向的内容就不再存在。最重要的是,您的功能try/finally
实现不正确。您必须遵循众所周知的标准模式,这种模式在很多地方都可以看到。我认为这不是重复的地方。
您需要进行彻底的重新设计。一些选项:
WideString
,因为这被分配掉一个共享堆返回字符串。WideString
用于利用共享的COM堆。本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句