2

現在、Delphi DLL を動的にインポートする際に問題が発生しています。Delphi DLL 関数は次のように宣言されます。

function TEST() : PChar; cdecl;
begin
  Result := '321 Test 123';
end;

C++ では、次のように呼び出しています。

typedef char *TestFunc(void);
TestFunc* Function;
HINSTANCE hInstLibrary = LoadLibrary("Test.dll");
if (hInstLibrary)
{
    Function = (TestFunc*)GetProcAddress(hInstLibrary, "TEST");
    if (Function)
    {
        printf("%s", Function());
    }
}

問題は、文字列の最初の文字しか受け取っていないことです。文字列が最初の文字の後で終わっていないことを C++ に伝えるにはどうすればよいですか?

ありがとう

4

1 に答える 1

2

2 つの問題があります。

  1. Delphi が送信する文字列は、UTF-16 でエンコードされています。PAnsiCharと一致させたい場合は、ANSI としてエンコードして返す必要がありますchar*
  2. 返されたポインタが参照するメモリは、関数が戻るときに割り当てが解除される可能性があります。DLL の存続期間中持続するグローバル定数として保持される文字列リテラルを返すため、関数内でそれを回避できます。文字列変数の場合、呼び出し元が割り当て解除されたメモリを読み込もうとすると、実行時エラーが発生します。問題を混乱させるために、これらの実行時エラーは断続的に発生します。コードが機能しているように見える場合があります。最も重要な顧客に展開するときの失敗を予期してください!

項目 2 を解決するためのオプション:

  1. 呼び出し元がバッファーを割り当てるように手配し、呼び出し先がデータを入力できるようにします。
  2. 共有ヒープで文字列を割り当ておよび割り当て解除します。たとえば、COM ヒープCoTaskMemAllocCoTaskMemFree. 共有ヒープを使用すると、1 つのモジュールで割り当てを行い、別のモジュールで割り当てを解除できます。

経験則として、ニーズを満たすことができる場合は、常にオプション 1 をお勧めします。

于 2013-04-19T10:47:10.437 に答える