これまで3つの回答が完全にあなたの質問のポイントを逃したようです。それ、または私は持っています。あなたはなぜWin32 Delphiに魔法のようなものがないのかを尋ねています。Supports
関数はHallvardの記事でお話しますね。つまり、DLLの名前とインタフェースの型情報が与えられた場合、DLLからエクスポートされたスタンドアロン関数を使用して、そのインタフェースを実装するオブジェクトを返します。
Hydraは、DLLから関数をインポートするのではなく、Win32プログラムから.Netコードを呼び出すことに関するすべてのようです。 TJvPluginManager
では、プラグインDLLが、DLLをロードするときにマネージャが呼び出す特別な自己登録機能をエクスポートする必要があり、その機能はTJvPlugin
クラスのインスタンスを返さなければならないため、プラグインDLLはDelphiまたはC++ Builder。一方、Supports
関数は、任意の言語で書かれたDLLで動作します。必要に応じて、kernel32で使用することができます。
Win32 Delphiにこのようなことがない理由はわかりません。 DelphiとTurbo Pascalがなくても、CodeGearはすでにそれほど長い間要求を受けていなかったかもしれません。
Microsoftの.Netライブラリが既にほとんどの部分を提供していない限り、.NET版よりも書くのが難しいとは思っていません。 Delphiは、Delphiが長年にわたって持っていたSupports
のいくつかの他のオーバーロードされたバージョンのように見える、便利なコール関数にそれらをラップします。
Win32でその機能を実装するには、いくつかの手順があります。 (私はDelphiの実行中のコピーを現在持っていないので、必要なものだけを提供しています。うまくいけば、もっと詳しく知ることができます)。まず、タイプを確認する必要があります少なくともメソッドの装飾されていない名前を保持するインターフェースの情報。次に、Supports
は、インターフェイス内の各メソッド(_AddRef、_Release、QueryInterface以外)の関数スタブを生成する必要があります。スタブは、呼び出し規約がstdcall
であると仮定すると、このような何かを行くだろう:
asm
// Pop the return address,
// discard the "this" pointer,
// and restore the return address
pop eax
pop ecx
push eax
jmp AddressOfFunction
end;
Supports
ように、各スタブを生成し、それは、対応するインターフェイスメソッドの名前でGetProcAddress
を呼び出すから得実際の関数アドレス、記入う。 stdcall
呼び出し規約は、そのように折り返すのは簡単です。 cdecl
はちょっと面倒です。 register
は首の痛みです。
すべてのスタブが生成されたら、指定されたインタフェースを実装するように見える「オブジェクト」を生成する必要があります。それは実際のクラスである必要はありません。コンパイル時に、Supports
は、実装するように頼まれる予定のインターフェースのレイアウトを知らないので、クラスを持っていてもそれほど成果は上がりません。
最後のステップは、_AddRef
,_Release
およびQueryInterface
の実装を提供することです。 _AddRef
は目立たないでしょう。 _Release
は、参照カウントがゼロに達したときにFreeLibrary
と呼ぶ場所です。 QueryInterface
は、IUnknown
をサポートし、インターフェイスがSupports
に指定されていることを除いて、まったく役に立たないでしょう。
デルファイでは、クラスなしでインターフェイスを実装することを実証したサンプルプログラムが付属していました。レコードと関数ポインタ(すべてのインターフェイスは最終的には結局のところです)ですべてが完了しました。 Delphiには、クラスでそれを行うための対応するコードが付属していました。私は今デモプログラムの名前を見つけることができませんが、私はそれがまだどこかにあると確信しています。
私はそれを私の回答で簡潔に述べました。これは私が行きたくないものの「ポインタを使って邪魔になる」ものです。ああ、そしてサイドボーナスとして、それはまた組立のまわりで醜いmuckingを含む。私はその部分を忘れてしまった! :P –
実際にはアセンブリではありません。マシンコード。私が上に書いたアセンブリは説明のためのものです。実行時にコードを生成するため、マシンコードを直接記述する必要があり、実行時アセンブラは使用できません。 –
+1、思いやりのある答え、技術的な詳細の素敵な説明。それを書く時間をとってくれてありがとう。 – mghie