1

Delphi6で外部C++DLLのエンコーディング関数を使用する必要があります。提供される宣言は次のとおりです。

long <Function Name> (char *Data, long &Apply, char *ReturnVal, long &Size)

Dataは入力値、Applyはブール値(デフォルト:FALSE)、ReturnValはDLLからの戻り値、SizeはReturnValの長さです。

これをDelphi6で使用するために、次のコードを記述しました。

implementation
   const
     EncoderDLL = '<DLL NAME>';
     FunctionName = 'FUNCTION NAME';
   var
      _TEST : function(const Data : PChar; Apply : PInteger;stOutput : Pchar;
          iSize : PInteger) : integer; stdcall;
   .....
   .....
   var
     stInput,stOutput : string;
     iLength,i1,iResult : integer;
     hnd : THandle;
   begin
     iLength := 0;
     i1 := 0;
     stInput := Trim(edtInput.Text);
     hnd := SafeLoadLibrary(EncoderDLL);
     if hnd > 0 then
     begin
       @_TEST := GetProcAddress(hnd,FunctionName);
       if @_TEST <> nil then
       begin
         iResult := _TEST(PChar(stInput),@i1,PChar(StOutput),@iLength); // ERROR
       end;
     end;
     FreeLibrary(hnd);
  end;

コメントとして「ERROR」が含まれている行にアクセス違反が発生しています。

関数宣言のPCharを文字列に置き換えると、アクセス違反は同じ行に発生しません。それはライブラリを解放している間に来ます。また、iLengthパラメーターの値が正しく入力されます。

誰かがこの問題を解決するためのポインタを提供できますか?

4

3 に答える 3

3
  1. stdcallコンベンションについてよろしいですか?C ++テキストに明確な指示(WINAPI、__ stdcallなど)がない場合は、cdeclを使用します。

  2. データが不要になる前の「const」

  3. StOutputにメモリを割り当てます

于 2012-10-05T11:21:00.900 に答える
3

私はReturnValそれが出力パラメーターであると仮定しています(関数がそれを埋めます)。コード内でこの文字列用のメモリを予約する必要があります。しかし、どのくらいのメモリを予約する必要がありますか?このような関数には一般的なパターンがあります。関数を2回呼び出します

最初の呼び出しで設定ReturnValするnilと、関数は必要なサイズをSizeパラメーターに入力します。

次に、その量のメモリをStOutputバッファに予約して、関数を再度呼び出します。今回は結果が得られます。

iResult := _TEST(PChar(stInput),@i1,nil,@iLength); // First call
SetLength( stOutput, iLength ); // reserve memory
iResult := _TEST(PChar(stInput),@i1,PChar(stOutput),@iLength); // Second call

この関数は、この規則に従う場合と従わない場合があることに注意してください。しかし、そうでない場合は、出力パラメータ用に予約する必要のあるメモリの量を判断する方法は実際にはありません。

注意すべきもう1つのことは、呼び出し規約です。CおよびC++関数のデフォルトはデフォルトでcdeclあり、表示した宣言はそれ以外のことを示していません。stdcallPascalのように宣言しました。それらは一致する必要があります。

于 2012-10-05T11:25:13.210 に答える
2

PCharを保持し、呼び出しの前にStOutputを空でない文字列(十分な長さ)に初期化します。

于 2012-10-05T11:13:23.327 に答える