COMプラグインと連携する必要のあるASP.NETMVC3Webサイトがあります。そのためには、なんらかの方法でインターフェースを定義する必要があります。私が理解している限り(私はCOMの専門家ではありません)、これは.NETで実行し、tlbexp.exeまたはidl->midl->tlbimpを使用してエクスポートできます。
私は最初の方法を実行しました(tlbexpを使用)。私もIDLを試しましたが、役に立ちませんでした(何らかの理由で、実装しているCOMオブジェクトを.NETのtlbimpされたインターフェイスにキャストして戻すことができました)。
インターフェイスにイベントがない場合、このシナリオは単純です。
[ComVisible(true)]
[Guid("EFCFB783-0225-4D45-94CB-9A26B7CC19AF")]
public delegate void ItemStatusChanged(string itemGuid, string itemStatus);
[ComVisible(true)]
[Guid("35202AE5-392D-4015-993D-29966DA5DE31")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface ICOMOutputPlugin
{
void Method1(string arg);
void Method2(string arg);
event ItemStatusChanged ItemStatusChanged;
}
[ComVisible(true)]
[Guid("93862C43-503C-4C96-9BAE-944F1087AB77")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface ICOMOutputPluginEvents
{
void ItemStatusChanged(string itemGuid, string itemStatus);
}
これをtlbexp.exeを使用してtlbにエクスポートし、.tlbをregtlibv12に登録します。プラグイン開発者は、このタイプライブラリのみを使用してインターフェイスをインポートします。
これで、プラグインとなるC ++プロジェクトができました。VS2010に新しい単純なATLオブジェクトを追加し、IDLを次のように変更します。
importlib("stdole2.tlb");
importlib("MyExp.tlb");
[
uuid(E09BC67A-4192-4CA3-8FD0-5CBFC69B43AC)
]
coclass DumpToFileOutputPlugin
{
[default] interface ICOMOutputPlugin;
[default, source] dispinterface ICOMOutputPluginEvents;
};
ここでの私の最初の問題は、何らかの理由で、クラスウィザードを介して「通常の方法」で接続ポイントを追加できなかったことです。MyExp.tlbに送信すると、ソースインターフェイスが表示されません。だから私はそれを手動で行いました(別の.tlbを使用し、すべての名前を変更しました)。
これで、次の2つのメソッドを持つCOMオブジェクトができました。
STDMETHOD(add_ItemStatusChanged)(_ItemStatusChanged* value);
STDMETHOD(remove_ItemStatusChanged)(_ItemStatusChanged* value);
.NET側では、プラグインマネージャーは次のようにプラグインをインスタンス化します。
Type type = Type.GetTypeFromProgID(progID);
comObject = Activator.CreateInstance(type) as ICOMOutputPlugin;
comObject.ItemStatusChanged += (guid, status) => ItemStatusChanged(guid, status);
add_ItemStatusChanged
最後の行は、COMオブジェクトのメソッドを奇跡的に呼び出しています。
ここで私は立ち往生しています、私はこの方法で何をすべきですか?私の現在の実装は次のとおりです。
HRESULT CDumpToFileOutputPlugin::add_ItemStatusChanged(_ItemStatusChanged* value)
{
DWORD cookie;
HRESULT ret = Advise(value, &cookie);
_com_error err(ret);
LPCTSTR errMsg = err.ErrorMessage();
return ret;
}
ret = CONNECT_E_CANNOTCONNECT(0x80040202)であり、errMsgは「IDispatcherror#2」と表示します。どうやらAdviseは、渡されたCOMオブジェクトが、渡されICOMOutputPluginEvents
たデリゲートオブジェクトが実装していない接続ポイントインターフェイスを実装することを期待しています...どうすればよいですか?
.NET側のイベントのサブスクリプションを間違っているのですか、それとも追加ハンドラーですか?
これを解決する方法の助けをいただければ幸いです。