最近、DLLモジュール(C#で作成されたもの)を含み、アプリケーションで使用する必要がある(アンマネージC ++で記述された)小さなプロジェクトを実行していました。これを機能させるには、ATL/COMを使用していました。
コアCOMインターフェイスを処理するためにC++アプリケーションで_com_ptr_tを使用しているにもかかわらず、C#オブジェクトのデストラクタは、アプリケーションが閉じられたときにのみ呼び出されることに気付きました。
物事をもう少し明確にするための情報源をいくつか紹介しましょう。
私のC#コードのいくつか:
[ComVisible(true)]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
public interface ITestCOM
{
[DispId(1)]
void Connect([In, MarshalAs(UnmanagedType.U2)] ushort value);
}
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces(typeof(ITestCOMEvents))]
public partial class TestCOM : ITestCOM
{
...
~TestCOM()
{
MessageBox.Show("DESTRUCTOR");
}
...
public void Connect(ushort value)
{
...
}
}
次のようなものを使用して.tlbファイルを作成しています: " RegAsm.exe TestCOM.dll /tlb:Test.tlb / codebase "
私のC++ヘッダーには次のものがあります。
#import "C:\...\mscorlib.tlb"
#import "......\TestCOM.tlb" named_guids exclude("ISupportErrorInfo")
#include <afxdisp.h>
#include <atlcom.h>
class Unit : public ::IDispEventSimpleImpl<0, Unit, &__uuidof(TestCOM::ITestCOMEvents)>
{
public:
BEGIN_SINK_MAP(Unit)
SINK_ENTRY_INFO(0, __uuidof(TestCOM::ITestCOMEvents), 0x1, OnEventCallback, &OnEventCallbackDef)
END_SINK_MAP()
...
private
TestCOM::ITestCOMPtr mTestCOM;
// NOTE: This would be the same as "_com_ptr_t<_com_IIID<TestCOM::ITestCOM, &__uuidof(TestCOM::ITestCOM)> > mTestCOM;"
}
そして、私のC ++ソースファイルは、次のように「mTestCOM」を作成します。
mTestCOM.CreateInstance(TestCOM::CLSID_TestCOM)
そして、基本的にはそれだけです。C#の「TestCOM」オブジェクトの関数は次のように使用できます。
mTestCOM->Connect(7);
問題は、C ++の「ユニット」オブジェクトが破棄されたときではなく、アプリケーションが閉じられたときにのみC#TestCOMオブジェクトのデストラクタが呼び出されるのはなぜですか。