2010-12-14 14 views
0

私はGeckoFx(http://geckofx.org)を拡張しようとしており、XPComが提供する管理されていないインタフェースから配列値を返す際にいくつかの問題を抱えています。管理されていないインターフェイスメソッドから値を正しく返す方法

最新のXulRunner 1.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]ですが、countは2の値で正しいままです。

この質問の最大の部分は 'Am Iメソッドとそのパラメータをインターフェイス宣言で正しくマーシャリングしますか? '

このサンプルコードは単なる例です。 GeckoFxに実装したい他のいくつかのXulRunner機能がありますが、配列を返しても同じ問題があります。私がこの問題を乗り越えるまで、私の仕事はちょっと待っています。

ご協力いただきありがとうございます。

-Scott

+0

配列引数から 'ref'キーワードを削除することをお勧めします。これは、データへのポインタへのポインタ(配列はC#での暗黙のポインタです)を意味し、私の推測ではポインタはデータへのポインタC配列に共通です)。 – cdhowie

+0

編集するためにアンマネージコードにアクセスできましたか? –

答えて

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); 

タイプミスかもしれません。)

+0

実際、私はそれを投稿してから数分後に自分自身で質問に答えました。上記の答えは、私が結局何をしたかに非常に近いです。 – Scott

関連する問題