3

私はこの問題について多くのことを検索しましたが、デルファイ dll から .NET に文字列を渡す方法について明確な答えはありません。次のコードは msdn ヘルプ ファイルに基づいています: http://msdn.microsoft.com/en-us/ライブラリ/4zey12w5.aspx

//Delphi code

function myDelphiFunc(var Buffer: PChar): Integer; export; stdcall;
  Buffer:='this is a test';
  Return:=0;
end;

//vb.NET code

<DllImport(path)> _
Public Function myDelphiFunc(ByVal buffer As String) As Integer

Public Sub myNETFunc()
  Dim buffer_size As integer = 25
  Dim buffer As String = New String(CChar(" "), buffer_size )
  Call myDelphiFunc(buffer)
  MsgBox(Strings.Left(buffer, InStr(buffer, Chr(0)) - 1))
End Sub

myDelphiFunc を呼び出すと、「buffer」変数に空の文字列が返されます。私は何を間違っていますか?

前もって感謝します

4

2 に答える 2

10

あなたのコードには多くの問題があります。主な障害は次のとおりです。

  • Delphi 関数は参照によってポインタを受け取りますが、VB コードはそれを値によって渡します。
  • Delphi コードは、指定されたバッファに文字列をコピーする必要があります。
  • Delphi コードは、VB と一致するように PAnsiChar を使用する必要があります。または、p/invoke の PWideChar および CharSet.Unicode。
  • VB コードでは、文字列を呼び出し元にマーシャリングするために、String ではなく StringBuilder を使用する必要があります。
  • 関数は、バッファ オーバーランを回避するために長さパラメータを受け入れる必要があります。

ただし、深く理解しようとする価値があるかどうかはわかりません。これを行う最も簡単な方法は、共有 COM ヒープに割り当てられた BSTR を使用することです。これにより、関数がはるかに使いやすくなり、すべてのメモリ割り当ての複雑さが隠されます。

デルファイ

procedure TestFunc(out str: WideString); stdcall;
begin
  str := 'foo';
end;

VB

<DllImport(path)> _ 
Public Sub TestFunc(<MarshalAs(UnmanagedType.BStr)> ByRef str As String)
于 2013-07-22T13:48:21.920 に答える
0

あなたのコードは

function myDelphiFunc(var Buffer: PChar): Integer; export; stdcall;
const
  tmp = 'this is a test';
begin
  Buffer := StrAlloc(Lenght(tmp)+1);
  StrPCopy(Buffer, PChar(tmp));
  Return:=0;
end;
于 2013-07-22T13:46:53.157 に答える