3

C ++からのバイト配列へのポインタを受け入れるdllがあり、このデータを次の方法でAnsiStringに移動しようとしています

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

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;

正常に動作しますが、SetStringでAVを提供する場合はC++からです。

これを手伝ってください。


RredCatから:

Yuriyの質問にいくつか説明を追加しましょう。まず、私たちが使用する言語についてです。C#プロジェクトでDelphidllを呼び出す必要があります。この目的のために、C ++ \ CLIレイヤー(プロキシ)を作成しました。次に、ヘッダーファイルのC ++\CLIコードについて説明します。

HINSTANCE hDelphiDLL;
typedef void (*pPBDFUNC)(byte* aBytes, int size);
pPBDFUNC Convert;

cppで、コンストラクターでConvertを設定しました。

hDelphiDLL = LoadLibrary(<path to dll>);

if(NULL != hDelphiDLL ){
    pPBDFUNC clb= GetProcAddress(HMODULE(hDelphiDLL), "Convert");
        if(NULL != clb){
            Convert= pPBDFUNC (clb);
        }...

そして、C#から呼び出す最後の1つのメソッド:

void Class1::Test(byte* aBytes, int size){
    Convert(aBytes,size);
}
4

2 に答える 2

5

Delphiコードは、バイト配列へのポインタへのポインタを渡します。バイト配列へのポインタのみを使用するように単純化します。

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

そしてそれを次のように呼びます

Convert(@Arr[0], Length(Arr));

また

Convert(Pointer(Arr), Length(Arr));

同じです。

于 2012-02-01T15:34:07.043 に答える
1

このタスクを必要以上に複雑にしています。C ++ / CLIは、既存のCまたはC ++コードの本体、または非常に大きなインターフェイスを備えたネイティブライブラリがある場合に最適です。ほんの一握りの関数しかない限り、ネイティブのDelphiDLLに直接p/invokeするのがここに行く方法です。

Sergは、Delphi関数の間接参照の偽の余分なレベルをすでに指摘しています。したがって、Delphi関数は次のように記述します。

procedure TestFunction(Text: PAnsiChar); stdcall;
var
  Buf: AnsiString;
begin
  Buf := Text;
end;

C#側では、次のように関数を宣言できます。

[DllImport(@"mydll.dll")]
static extern void TestFunction(string Text);

この関数は、次のようにC#コードから呼び出すことができます。

TestFunction("Hello");
string str = GetStringFromSomewhere();
TestFunction(str);

以上です!C#の最後には文字列変数があるので、p / invokeマーシャラーを使用して、ネイティブコードにnullで終了する文字列を提供できます。したがって、長さを渡す必要はありません。p / invokeのデフォルトの呼び出し規約はstdcall、Delphiコードのそれを優先します。

于 2012-02-01T18:38:54.173 に答える