Как правильно вернуть значения из неуправляемого метода интерфейса? - PullRequest
0 голосов
/ 14 декабря 2010

Я нахожусь в процессе расширения GeckoFx (http://geckofx.org), и у меня возникают некоторые проблемы с возвратом значений массива из неуправляемых интерфейсов, предоставляемых XPCom.

Я добавил большое количество поддержки новых функций в GeckoFxиспользуя последнюю сборку XulRunner 1.9.2.13, но я получаю исключения нарушения прав доступа при попытке вернуть массивы из методов интерфейса. Например:

[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 возвращается, иногда он возвращает список содин индекс, содержащий имя одного словаря (у меня есть 2 словаря в том месте, где этот метод выполняет поиск), и count возвращается с правильным значением 2, в других случаях метод завершится ошибкой и вызовет нарушение прав доступа, а значение _dictionaries равноstring [0], в то время как count остается верным со значением 2.

Я думаю, что большая часть этого вопроса должна была бы быть: «Я правильно марширую метод и его параметры в объявлении интерфейса?».

Этот пример кода только что - пример.Есть несколько других функций XulRunner, которые я хотел бы реализовать в GeckoFx, но они также возвращают массивы и страдают от той же проблемы.Пока я не справлюсь с этой проблемой, моя работа находится в тупике.

Спасибо за любую помощь, которую вы можете предоставить.

-Скотт

1 Ответ

0 голосов
/ 14 декабря 2010

Измените:

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

(я не скомпилировал этот код, поэтому возможнобыть опечатками.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...