正确将字节从C++转换为delphi AnsiString

Yur*_*riy 3 c# c++ delphi interop data-conversion

我有dll接受来自C++的字节数组的指针,并尝试通过以下方式将此数据移动到AnsiString中

procedure Convert(const PByteArr: Pointer; ArrSize: Cardinal); export; cdecl;
var
  Buf: AnsiString;
begin
  SetString(Buf, PAnsiChar(PByteArr^), ArrSize);
end;
Run Code Online (Sandbox Code Playgroud)

如果我从Delphi调用这个方法

procedure Try;
var
  M: TMemoryStream;
  Arr: TBytes;  
begin
  M := TMemoryStream.Create;
  try
    M.LoadFromFile('myfile.dat');
    SetLength(Arr, M.Size);
    M.Position := 0;
    M.Read(Arr[0], M.Size);
  finally
    M.Free;
  end;
  Convert(@Arr, Length(Arr));
end;
Run Code Online (Sandbox Code Playgroud)

它工作正常,但从c ++如果在SetString上提供AV.

请帮我解决一下这个.


来自RredCat:

让我为Yuriy的问题添加一些解释:首先是我们使用的语言.我们需要在C#项目中调用Delphi dll.为此,我创建了C++\CLI层(代理).现在关于头文件中的C++\CLI代码:

HINSTANCE hDelphiDLL;
typedef void (*pPBDFUNC)(byte* aBytes, int size);
pPBDFUNC Convert;
Run Code Online (Sandbox Code Playgroud)

在cpp中我在构造函数中设置Convert:

hDelphiDLL = LoadLibrary(<path to dll>);

if(NULL != hDelphiDLL ){
    pPBDFUNC clb= GetProcAddress(HMODULE(hDelphiDLL), "Convert");
        if(NULL != clb){
            Convert= pPBDFUNC (clb);
        }...
Run Code Online (Sandbox Code Playgroud)

我从C#调用的最后一个方法:

void Class1::Test(byte* aBytes, int size){
    Convert(aBytes,size);
}
Run Code Online (Sandbox Code Playgroud)

klu*_*udg 5

您的Delphi代码传递指向指向字节数组的指针.简化它只使用指向字节数组的指针:

procedure Convert(const PByteArr: Pointer; ArrSize: Cardinal); export; cdecl;
var
  Buf: AnsiString;
begin
  SetString(Buf, PAnsiChar(PByteArr), ArrSize);
end;
Run Code Online (Sandbox Code Playgroud)

并称之为

Convert(@Arr[0], Length(Arr));
Run Code Online (Sandbox Code Playgroud)

要么

Convert(Pointer(Arr), Length(Arr));
Run Code Online (Sandbox Code Playgroud)

这是一样的.