0

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側のイベントのサブスクリプションを間違っているのですか、それとも追加ハンドラーですか?

これを解決する方法の助けをいただければ幸いです。

4

1 に答える 1

-1

ASP.Net の COM プラグインで「イベント」を使用しないでください。呼び出すメソッドだけを使用してください。OnEventNameつまり、イベントではなく呼び出されるメソッドです。

COM イベントは、Web フォームのポストバックを処理するのに適したものではありません。

于 2012-07-04T14:19:36.260 に答える