0

私はGeckoFx(http://geckofx.org)を拡張している最中であり、XPComが提供するアンマネージインターフェイスから配列値を返す際に問題が発生しています。

最新のXulRunner1.9.2.13ビルドを使用してGeckoFxに大量の新機能サポートを追加しましたが、インターフェイスメソッドから配列を返そうとするとアクセス違反の例外が発生します。例えば:

[Guid("43987F7B-0FAA-4019-811E-42BECAC73FC5"), ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface mozISpellCheckingEngine
{
    //...
    void GetDictionaryList([MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPWStr)]ref string[] dictionaries, out uint count);
    //...
}

public static string[] GetAvailableDictionaries()
{
    string[] _dictionaries = null;
    uint count = 0;

    //GetSpellChecker() returns a valid mozISpellCheckingEngine object
    GetSpellChecker().GetDictionaryList(ref _dictionaries, out count);
    if (count > 0)
    {
        if (_dictionaries != null)
        {
            return _dictionaries;
        }
    }
    return null;
}

問題は、GetDictionaryListが返されるときに、単一のインデックスを持ち、1つのディクショナリの名前を含むリストを返し(このメソッドが検索する場所に2つのディクショナリがあります)、カウントが正しい値2で返されることです。それ以外の場合、メソッドは失敗してアクセス違反をスローし、_dictionariesの値はstring [0]ですが、カウントは2の値で正しいままです。

この質問の最大の部分は、「インターフェイス宣言でメソッドとそのパラメーターを正しくマーシャリングしていますか?」である必要があると思います。

このサンプルコードはまさにその例です。GeckoFxに実装したいXulRunnerの機能は他にもいくつかありますが、それらも配列を返し、同じ問題が発生します。この問題を乗り越えることができるまで、私の仕事は少し停滞しています。

あなたが提供できるありとあらゆる助けに感謝します。

-スコット

4

1 に答える 1

0

変化する:

void GetDictionaryList([MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPWStr)]ref string[] dictionaries, out uint count);

に:

void GetDictionaryList(ref IntPtr dictionaries, out uint count); 

次のように使用します。

IntPtr dictionaries = IntPtr.Zero;
int count;

GetDictionaryList(ref dictionaries, count);

 // check dictionaries != IntPtr.Zero; and count > 0

 // dictionaries will be a IntPtr to array IntPtr (of size count)

 string vals = new string[count];

 for(int i = 0; i < count; ++i)
  vals[i] = Marshal.PtrToStringUni(Marshal.SizeOf(typeof(IntPtr)) * i);

(このコードはコンパイルしていないため、タイプミスがある可能性があります。)

于 2010-12-14T08:18:05.697 に答える