2

私が働いている会社は、複数の製品に適用でき、これらの製品は異なる言語で書かれているため、一部のソフトウェアにいくつかの機能が必要でした。すべてWindowsでのみ実行されますが、COMサーバーに実装するのは良い選択のようです。私はPythonとpywin32拡張機能を使用してCOMサーバーを作成したので、アクセスは遅延バインディングであり、IDispatchであると信じています。

現在、COMサーバーのJavaバインディングを作成しようとしています。ディスパッチインターフェイスを使用する必要があるため、JACOBを使用してCOMにアクセスすることにしました(これは最近更新されたプロジェクトの1つであり、ニーズに適合しているようです)。COMにかなり慣れておらず、COMサーバーがラップするライブラリのマルチスレッドに関する問題は実際には見られないため、最初はCOMスレッドにほとんど注意を払わなかったため、提供されたスレッドのものを使用しなかったCOMオブジェクトのJavaバインディングJACOBによると、その簡単なテストはOracleのJVMで正常に機能しました。

しかし、COMスレッドを無視できないことが明らかになりました。1つの問題は、Java製品がExcelsior Jetを使用してコンパイルされていることです。これは、何らかの理由でJavaでCOMオブジェクトを解放しなかったため、アプリケーションを終了した後もCOMサーバー(別の.exe)が実行され続けました。もう1つの問題は、実際には複数のスレッドからのCOMオブジェクトを使用する必要があるということです。私の最初のアプローチは、COMオブジェクトを複数のスレッドで使用できないという問題にぶつかっていました。

JACOBディストリビューションのCOMオブジェクトの処理方法に関するドキュメント(参照カウントVS GCに関するドキュメントと複数のスレッドのドキュメントの両方)を読みました。これらと、複数のスレッドでCOMオブジェクトを使用して適切に解放する方法を理解していると思います(各スレッドにJACOBのComThread.Release()を使用すると、Excelsior JetもCOMオブジェクトを解放します)。

私の考えでは、マルチスレッドアパートメントはCOMサーバーで問題ないはずなので、JACOBのドキュメントによると、COMオブジェクトを使用する前に各スレッドがcom.jacob.com.ComThread.InitMTA()を呼び出してから、com.jacobを呼び出す必要があります。 COMオブジェクトを使用する各スレッドの最後にある.com.ComThread.Release()。また、このドキュメントでは、おそらくJACOBにメインSTAを作成してもらいたいと示唆しているため、これは、アプリケーションのシャットダウン時にメインSTAを終了するための呼び出しも意味します。

私の質問は、スレッドの最初で物事を呼び出すことは、Javaのやり方に実際にはうまく適合していないようですが、特にCOMのこれらの特殊性から、アプリケーションの残りの部分を分離する方法はありますか?スレッド領域?

アプリケーションはCOMオブジェクトではなくバインディングを直接使用しているので、これらのラッパークラス内で処理できるかどうかを検討しました。ただし、COMオブジェクトにアクセスするラッパーオブジェクトのすべてのメソッドでComThread.InitMTA()とComThread.Release()を呼び出すことしか考えられないようです。これは非効率に感じますが、ComThread.InitMTA()とComThread.Release()の呼び出しが実際にどれだけ行われるかはわかりません。そのため、最初に思われるほど悪くはないかもしれません。

私の他の考えは、このライブラリを使用したごく初期の頃、COMサーバーを使用して実際に何かをリリースしたとは思わないので、使用するより良いテクノロジ(RPC、XMLRPCなど)があるでしょうか。このような変更は、現時点ではそれほど苦痛ではないでしょう。

ライブラリが実行していることに関する少しのコンテキストを提供するために、主にさまざまな音声出力APIを1つにラップします(たとえば、SAPI4、SAPI5、およびその他のいくつかにアクセスするための共通のインターフェイスを提供します)。したがって、ほとんどの呼び出しは、システムに何かを言う、音声を消す、または設定を変更するように指示しているだけです。一般に、ライブラリとの通信は非常に単純です(文字列の配列を返すことは、それが得るのと同じくらい複雑だと思います)。

4

1 に答える 1

0

これは、アスペクト指向プログラミング (AOP) の非常に良い候補のように思えます。Java で支配的なフレームワークはAspectJですが、ほとんどの人はそれをSpring-AOPのコンテキストで使用します。要件とアーキテクチャに応じて、さまざまな方向に進むことができます。

  1. コンパイル時のウィービング - ポイントカットとアドバイスは、特別なコンパイラーによってコンパイル時に適用 (「ウィービング」) されます。
  2. ロード時のウィービング - JVM エージェントによって実行時にポイントカットとアドバイスが適用されます
  3. 動的プロキシ - 動的プロキシ ファサードでアドバイスされたクラスをラップすることにより、ポイントカットとアドバイスが実行時に適用されます (これが Spring-AOP の方法です)。

aspectj weavingに関するこのかなり良い記事を見つけました。

于 2012-10-15T11:25:54.410 に答える