2

いくつかのクラスを含むマネージ アセンブリがあり、それらのクラスにはオーバーロードされたメソッドがあります。アセンブリを COM/IDispatch 呼び出し元に公開します

[ComVisible(true)]

..また、アセンブリ自体に適切な Guid を設定します。COM 相互運用のための明示的なインターフェイスは定義しません。すべて動的に行われます。regasm.exe /codebaseマネージ DLL で実行すると、COM 相互運用に登録されます。

OleView を実行すると、アセンブリ内のさまざまなクラスの ProgId を確認できます。しかし、これらの ProgId を参照し、IDispatch ノードを展開すると、これらのクラスの TypeLib 情報がありません。

それでも、スクリプトから、引数を 0 個受け取るメソッドまたは 1 個の引数を受け取るメソッドを呼び出すことができます。複数の引数を受け入れるオーバーロードもある場合、そのメソッドを名前で呼び出すことはできません。私が一貫して得るエラーは

Microsoft VBScript runtime error: Wrong number of arguments or invalid property assignment:  <methodname>

このことから、COM/IDispatch クライアントは、COM 相互運用機能を介して公開されたオブジェクトのオーバーロードされたメソッドを適切に解決できないことがわかりました。


それから私は追加しました

[ClassInterface(ClassInterfaceType.AutoDual)]

...問題の各クラスに。DLL の実行後regasm.exe、IDispatch ノードの下に各メソッドの typelib 情報が表示されます。

私が見つけたのは、オーバーロードされたメソッドは、追加されたサフィックスを含む名前を自動的に取得するということです。MethodX は、自動生成された typelib アセンブリのオーバーロードを MethodX、MethodX_2、MethodX_3 などとして公開します。

そして、これらの接尾辞を使用してメソッド名を参照することで、オーバーロードされたメソッドを呼び出すことができることがわかりました。ただし、一般的な名前ではありません。

さらに興味深いことに、[ClassInterface(ClassInterfaceType.AutoDual)]クラスからを削除した場合でも、オーバーロードされたメソッドをこの方法で呼び出すことができ、 Wrong number of arguments or invalid property assignmentエラーを回避できました。

私の質問は: この動作 - メンバー名に数字の接尾辞を追加する - は安定していますか? 文書化されていますか?信頼できる?

4

3 に答える 3

5

COM はメソッドのオーバーロードをサポートしていないため、.NET COM 相互運用レイヤーは即興で作成する必要があります。あなたが説明したような名前マングリングがどこかに文書化されているかどうかはわかりませんが、たとえそうであっても、それを使用することは良い考えではないと思います.COMユーザーにとってはまだかなり不便なAPIです. クラスを COM に公開する場合、最善の方法は、COM に適した別個の[ComVisible]インターフェイスを作成し、クラス自体を非表示にすることです。COM フレンドリーな方法でオーバーロードを処理する正しい方法は、いくつかの[Optional]引数を持つ単一のメソッドを持つことです (そして、対応する .NET オーバーロードにデリゲートします)。

于 2009-08-15T02:04:24.070 に答える
1

はい、MSDN に記載されています。

それを変更すると、文書化された機能の「重大な変更」になるため、「安定」していると信頼できると思います。大きな欠点は、メソッド名がソース ファイルで定義されている順序に依存することです。

ただし、COM はオプションの引数をサポートしているため、それらを使用することはオーバーロードの実行可能な代替手段になる可能性があることに注意してください。ライブラリの古い .NET クライアントにバイナリ互換性を持たせるためにオーバーロードを追加する必要がある場合は、次のパターンが役立つことがわかりました。

// used for binary-compatibility with .NET clients who currently use 
// the old, one-parameter version
[ComVisible(false)]
void myMethod(String oneParameter) {   
    ... 
}   

// since this is the first COM-visible version, it is assigned the "correct" name.
void myMethod(String oneParameter, int newParameter = 0) {
    ...
}

COM はオプションのパラメータをサポートしているため、myMethod(string)との両方myMethod(string, int)が機能します。

于 2012-10-25T09:11:37.157 に答える