2

まず、私は Delphi と COM の初心者ですが、Delphi で COM アプリケーションを作成する必要があります。インターネットで多くの記事やメモを読みましたが、COM と Delphi の 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 について何を読むことができますか?

4

3 に答える 3

2

自分で IUnkown.QueryInterface を実装する必要はありません。そのメソッドを TestComImpl から削除し、TComObject に処理させます。また、必ず ITestCom インターフェイスに GUID を指定してください。

于 2010-04-23T12:46:41.307 に答える
0

QueryInterfaceが戻​​った後にクラッシュが発生している場合は、JavaアプリがQueryInterfaceを呼び出したときにブレークポイントを設定し、次に何をしようとしているのかを確認します。それはあなたにどこを見るべきかについての考えを与えるでしょう。

あなたのコメントはこれを裏付けているようです。これはQueryInterfaceを呼び出して、このインターフェイスが優れているという結果を返し、すぐに壊れてしまうものに使用しようとしています。しかし、インターフェースが良好であることを示すコードをコメントアウトすると、インターフェースを使用しようとせず、何も壊れません。

Delphiに精通していない場合、アクセス違反は通常、nullポインタの逆参照を意味します。ここでは、命令ポインタがメモリ位置0x000002にあることを示しています。これはおそらく、まだ構築されていないオブジェクトに対して仮想メソッド(またはインターフェイスメソッド)を呼び出そうとしたことを意味します。

お役に立てば幸いです。

于 2010-04-23T12:07:29.493 に答える
0

COMでdllを一から作り、

  1. 私は DllRegisterServer を使用しています - サーバー登録を制御する可能性がありました (私の最初の試みでは TComObjectFactory.RegisterClassObject を介して)
  2. TestComImpl から QueryInterface を削除します
  3. Com4j は STA (Apartment) スレッド モデルのみをサポートします (RegisterClassObject は MTA を使用すると仮定します)。
  4. したがって、クラスがアパートメント (STA) または両方として登録されている場合、com4j はインスタンスを作成できます。

みんな助けてくれてありがとう!

于 2010-04-26T08:51:26.267 に答える