2

コードを VSTO から ExcelDna に移動していたところ、奇妙なエラーが発生しました。

以前の VSTO 関数を含む新しいプロジェクトを Visual Studio で作成しました。VBA でこれらの関数にアクセスするために Excel VBA で参照する .tlb ファイルを生成するために、[COM 相互運用に登録する] オプションをオンにしました。

1つの関数について、エラーがあります:

「アセンブリ "C:\MyProj.dll" をタイプ ライブラリに変換できませんでした。タイプ ライブラリ エクスポータで、'GetArrayObject' の処理中にエラーが発生しました。エラー: 型が一致しません。」

Com 可視インターフェイスの関数 GetArrayObject の定義は次のとおりです。

[ComVisible(true)]
//[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IAddInUtilities
{
    object[,] GetArrayObject(string[] rows = null);
}

次の定義が機能します。

object[,] GetArrayObject(string[] rows);

COM の既知の制限ですか? C++ の制限 (配列引数のデフォルト値) が原因でしょうか? COMではなくVSTOで機能する理由はありますか?

助けてくれてどうもありがとう

4

1 に答える 1

3

これは大きなエラー メッセージではありません。この問題は、作業中のバージョンのインターフェイスで Oleview.exe ファイル + View Typelib を実行すると発生します。わかるでしょ:

interface IAddInUtilities : IDispatch {
    [id(0x60020000)]
    HRESULT GetArrayObject(
                    [in] SAFEARRAY(BSTR) rows, 
                    [out, retval] SAFEARRAY(VARIANT)* pRetVal);
};

string[] が SAFEARRAY (配列の標準オートメーション型) としてマーシャリングされる方法に注意してください。また、参照ではなく値で渡されることに注意してください。つまり、null にすることはできません。それ以外の場合、SAFEARRAY の既定値の指定はサポートされていません。

参照によって配列を渡す必要があります。C# ではrefキーワードです。しかし、C# 言語の規則で問題が発生し、既定値を指定できなくなります。

次の試みは、配列をポインター BSTR* として強制的にマーシャリングすることです。これはどちらかというと SAFEARRAY の対蹠地です。その 1 つは、COM サーバーが単純なポインターからそれを把握できなくなったため、配列内の要素の数を示すために追加の引数を追加する必要があることです。このような:

public interface IAddInUtilities {
    object[,] GetArrayObject(
        int rowcnt,
        [MarshalAs(UnmanagedType.LPArray)]string[] rows = null
    );

これは問題なく変換されます。ただし、Oleview.exe を使用してタイプ ライブラリを見ると、次のように表示されます。

interface IAddInUtilities : IDispatch {
    [id(0x60020000)]
    HRESULT GetArrayObject(
                    [in] long rowcnt, 
                    [in, optional, defaultvalue("")] BSTR* rows, 
                    [out, retval] SAFEARRAY(VARIANT)* pRetVal);
};

うーん、デフォルト値が間違っています。他の唯一のオプションは、Oleview.exe から取得した IDL を使用し、それを編集して defaultvalue() を変更し、midl.exe でコンパイルしてタイプ ライブラリを生成し、Tlbimp.exe を使用して相互運用ライブラリを生成することです。 . その後、プロジェクト + 参照の追加を使用してプロジェクトに追加できます。これがマイナーな便利さの手間をかける価値があるかどうかは正確にはわかりませんが、電話をかけるのはあなた次第です.

于 2013-07-16T11:01:07.713 に答える