4

Delphiでポインターが実際にどのように機能するかを理解していないため、大きな問題があります

まず、dll から関数宣言を取得します。

関数:

type
  TMICRCallback   = function: Integer; stdcall;

次に、コードで関数を宣言します。

function CBMICRRead : Integer;stdcall;

関数はとてもシンプルです (これは一例です)

function TCustomizedTenderPlugin.CBMICRRead : Integer; stdcall;
var
  SUCCESS:integer;
begin
   SUCCESS:=1;
   Result:= SUCCESS;
end;

このように変数を宣言します

Respuesta : TMICRCallback;

この変数を関数に割り当てようとすると、問題が発生します:(

Respuesta      := CBMICRRead;

Delphiでポインタを使用するのはこれが初めてなので、ばかげた質問かもしれませんが、助けてください

4

3 に答える 3

6

TCustomizedTenderPlugin.CBMICRReadインスタンスメソッドです。つまり、それを呼び出すには、それを呼び出すインスタンスが必要です。

一方、TMICRCallback関数ポインタです。インスタンスメソッドではなく、プレーンな関数と互換性があります。

それらは単に互換性がありません。TCustomizedTenderPlugin.CBMICRReadと互換性を持たせるには、次のTMICRCallbackように定義する必要があります。

TMICRCallback = function: Integer of object; stdcall;

of object、この型がインスタンス メソッドと互換性があることを示します。タイプの変数TMICRCallback(この回答で定義されている) は、関数ポインターとインスタンス ポインターの両方を保持します。2 ポインター関数型と呼ばれることもあります。

先に進む前に、ドキュメントを注意深く読むことをお勧めします。


stdcallこれらの関数ポインターの呼び出し規約を使用していることに注意してください。これは通常、外部モジュールとの相互運用を試みていることを示しています。これは、インスタンス メソッドでは信頼できるものではありません。of objectつまり、Delphi 以外の言語ではインスタンス メソッドを実装できないということです。このコードが相互運用設定で使用される予定である場合は、使用を控えてくださいof object

相互運用設定の場合、通常はインスタンス ポインターを別のパラメーターとして含めます。その場合、Delphi 宣言は次のようになります。

type
  TMICRCallback = function(Data: Pointer): Integer; stdcall;

次に、このような関数を実装します

type
  TPlugin = class
    function CBMICRRead: Integer;
  end;

.....

function PluginCBMICRReadCallback(Data: Instance): Integer; stdcall;
begin
  Result := TPlugin(Data).CBMICRRead;
end;

function TPlugin.CBMICRRead: Integer;
begin
  Result := ....
end;

最後に、コールバックが渡される外部モジュール内の関数にはPluginCBMICRReadCallback、インスタンスのインスタンス ポインターと両方を渡す必要がありTPluginます。おそらく、このような少し:

procedure RegisterCallback(Callback: TMICRCallback; Data: Pointer); stdcall;

次のように呼び出します。

var
  Plugin: TPlugin;
....
Plugin := ...;//get this instance from somewhere
RegisterCallback(PluginCBMICRReadCallback, Plugin);

関連する質問で C++ コードを見ると、インターフェイスの C++ 側は次のようになります。

int WINAPI BiMICRSetReadBackFunction(int    nHandle, 
                                     int    (CALLBACK *pMicrCB)(void),
                                     LPBYTE pReadBuffSize,   
                                     LPBYTE readCharBuff,    
                                     LPBYTE pStatus,         
                                     LPBYTE pDetail); 

このコールバックはデータ ポインターを受け入れないため、インスタンス メソッドをまったく使用できません。複数のインスタンスのコールバックをどのように実装するつもりなのかは、私にはわかりません! とにかく、次のように Delphi でこの関数を宣言できます。

type
  TMICRCallback = function: Integer; stdcall;

function BiMICRSetReadBackFunction(
  nHandle: Integer;
  MicrCB: TMICRCallback;
  pReadBuffSize: PByte;
  readCharBuff: PByte;
  pStatus: PByte;
  pDetail: PByte
): Integer; stdcall; external dllname;

それを呼び出すには、これが必要です:

function MICRCallback: Integer; stdcall;//not the method of a class
begin
  Result := ....
end;
.....
retval := BiMICRSetReadBackFunction(..., MICRCallback, ....);
于 2012-10-09T16:17:16.287 に答える
0

DLL 内の関数の宣言が、記述したオブジェクト メソッドではない場合は、その関数をオブジェクトのメソッドではなくグローバル関数として宣言するか、オブジェクトの静的クラス関数として宣言することで解決できます。物体。

class function CBMICRRead: Integer; static; stdcall;
于 2012-10-09T16:22:00.607 に答える
0

は明らかCBMICRReadにオブジェクト メソッド (つまり、 のメソッドTCustomizedTenderPlugin) として定義されているため、「スタンドアロン」関数ではありません。このため、あなたがする必要があります

type
  TMICRCallback   = function: Integer of object; stdcall;
于 2012-10-09T16:13:10.147 に答える