Инициализация ссылки SAFEARRAY в C # (порт от VB?) - PullRequest
1 голос
/ 21 ноября 2011

Я работаю со сторонним компонентом COM (т.е. не имею его код). Данный метод имеет следующую схему:

HRESULT GetTableInfo(  
[in] BSTR bstrTableName, 
[in,out] SAFEARRAY(BSTR) bstrColumnTitles, 
[in,out] SAFEARRAY(long) lColumnPos );

Я пытался передать ссылку на массив фиксированного размера ((Array) string [6]) и в List.ToArray (), но он продолжает падать на мне. Э.Г.

Array arr1 = (Array) new string[500];
Array arr2 = (Array) new int[500];
table.GetTableInfo(filename, ref arr1, ref arr2);

Чтобы быть более конкретным: я уже пробовал любое значение для размера (правильное должно быть 44). Пробовал то же самое для емкости List <>, но это тоже не помогло. Я также пробовал разные типы, но он не принимает ничего, кроме int.

Я не знаю, почему он продолжает зависать на мне из-за общей ошибки этого COM-компонента (в основном, указывает на то, что что-то не так, но не говорит, что именно), поскольку я могу подтвердить, что работает следующий код VB:

Dim TitleList() As String
Dim PositionList() As Long 
Call objTable.GetTableInfo(txTableFile.Text, TitleList, PositionList)

Кто-нибудь знает, почему это происходит? Или, в качестве альтернативы, кто-нибудь может предоставить мне порт этого кода VB для C #? Я пытался найти в Google учебники, но все, что они говорят, это «разрешены только массивы фиксированного размера». Интересно, как тогда работает этот код, так как размер не указан?

Спасибо, я.

1 Ответ

1 голос
/ 21 ноября 2011

Вы прочитали Маршалинг по умолчанию для массивов ? Насколько я могу судить, это должно "просто работать", если вы используете атрибут MarshalAs в объявлении PInvoke, чтобы указать, что массив должен маршалироваться как безопасный массив.

Насколько я могу судить, правильное объявление PInvoke должно быть примерно таким:

public static string extern GetTableInfo(
    string tableName,
    [MarshalAs(UnmanagedType.SafeArray, SafeArraySubType=VT_BSTR)]
    ref string[] columnTitles,
    [MarshalAs(UnmanagedType.SafeArray, SafeArraySubType=VT_I8)]
    ref long[] columnPos
);

Можете ли вы показать нам, как выглядит ваша декларация PInvoke?

...