Delphi の GetInterface/QueryInterface 後のアクセス違反
-
01-10-2019 - |
質問
まず、私は Delphi と COM の初心者ですが、Delphi で COM アプリケーションを構築する必要があります。インターネット上の多くの記事やメモを読みましたが、Delphi の COM と COM はまだよくわかりません。
私の情報源 - http://www.everfall.com/paste/id.php?wisdn8hyhzkt (約80行)。
COM インターフェイスと Impl クラスを作成しようとしています。Delphi からインターフェイス メソッドを呼び出すと (TestClient.Create を介して impl オブジェクトを作成します)、機能しますが、外部の世界から (Java から、com4j を介して) オブジェクトを作成しようとすると機能します。 ) 私のアプリケーションは次の例外でクラッシュしました:
Project Kernel.exe raised exception class $C0000005 with
message 'access violation at 0x00000002: read of address 0x00000002'.
QueryInterface にブレークポイントを設定すると壊れますが、関数から抜け出すとすべてがクラッシュします。
私の何が間違っているのでしょうか?私にまだ足りないものは何でしょうか?このような愚かな質問を避けるために、(Delphi の) COM について何を読むべきですか?
解決 3
ゼロからcomを使用してdllを作成しました
- 私はdllregisterserverを使用しています - それは私にサーバー登録を制御する可能性を与えてくれました(私の最初の試みでtcomobjectfactory.registerclassobjectを介して)
- testcomimplからqueryinterfaceを削除します
- com4JはSTA(アパート)スレッドモデルのみをサポートします(RegisterClassObjectがMTAを使用していると仮定しています)
- したがって、クラスがアパート(STA)またはその両方として登録されている場合-COM4Jはインスタンスを作成できます。
助けてくれてありがとう!
他のヒント
iunkown.queryinterfaceを実装する必要はありません。 TestComimplからそのメソッドを削除し、tcomobjectに処理させます。また、itestcomインターフェイスにGUIDを提供してください。
QueryInterface が戻った後にクラッシュが発生している場合、Java アプリが QueryInterface を呼び出すときにブレークポイントを設定し、次に何をしようとするかを確認します。そうすれば、どこを見るべきかがわかります。
あなたのコメントはこれを裏付けているようです。QueryInterface を呼び出して、このインターフェイスが良好であるという結果を返し、それをすぐに壊れる何かに使用しようとしています。しかし、インターフェイスが良好であることを示すコードをコメントアウトすると、インターフェイスは使用されなくなり、何も壊れません。
Delphi に詳しくない方のために説明すると、アクセス違反は通常、null ポインタの逆参照を意味します。ここでは、命令ポインタがメモリ位置 0x000002 にあることが示されています。これはおそらく、まだ構築されていないオブジェクトに対して何らかの方法で仮想メソッド (またはインターフェイス メソッド) を呼び出そうとしたことを意味します。
お役に立てば幸いです!