OpcRcw.da.dllを使用しようとしています。テストコンソールプロジェクト内でこのdllを相互運用すると、すべてが機能しますが、dllプロジェクトをビルドして相互運用体操を行い、ライブラリをコンソールプロジェクトに参照すると、このエラーが発生します。
基礎となるRCWから分離されたCOMオブジェクトは使用できません。
RCW refを殺さないために、クラスlibプロジェクトに何をする必要がありますか?
実際のアプリケーションが何をしているのかを伝えるのは少し難しいですが、COMオブジェクトをインスタンス化し、Timer.Elapsedイベントなどで別のスレッドからアクセスしようとしているようです。アプリケーションがマルチスレッドの場合、使用する各スレッド内でCOMオブジェクトをインスタンス化する必要があります。
これにはいくつかの理由がありますが、私が知っている大きな理由は以下のとおりです。
デリゲートへの強い参照のないイベントハンドラ
呼び出し元は、コールバックデリゲートへの強い参照を保持せずに、comオブジェクトのイベントにサブスクライブします。これを正しく行う方法としない方法の例を次に示します。これは、デリゲートへの強い参照を保持する必要があるためです。スコープから外れると、ラッパーはインターフェイスの参照カウントを解放します悪いことが起こります。
public class SomeClass
{
private Interop.ComObjectWrapper comObject;
private event ComEventHandler comEventHandler;
public SomeClass()
{
comObject = new Interop.ComObjectWrapper();
// NO - BAD!
comObject.SomeEvent += new ComEventHandler(EventCallback);
// YES - GOOD!
comEventHandler = new ComEventHandler(EventCallback);
comObject.SomeEvent += comEventHandler
}
public void EventCallback()
{
// DO WORK
}
}
破棄されたランタイム呼び出し可能ラッパーの呼び出し
ラッパーは破棄されており、破棄後に呼び出しが行われています。これが発生する一般的な方法は、コントロールがactivexコントロールまたはCOMオブジェクトを使用しており、コントロールのDispose()が順番どおりに呼び出されない場合です。
デバッグ手順
この問題をデバッグする良い方法は、次を実行することです。
もう1つ
これはこの問題とは関係ありませんが、このトピックについては、特にご存じない限り、COMオブジェクトが使用されているスレッドがSTAとしてマークされていることを必ず確認してください。これを行うには、デバッガーを中断し、次から返される値を確認します。
Thread.CurrentThread.GetApartmentState();