2014-01-03 2 views
1

Я определил структуру MyStructure в IDL неуправляемой библиотеки SomeLibrary. Мне нужно вызвать управляемый код (C#) MyManagedLibPtr-> RetrieveStuff из неуправляемой библиотеки (C++), чтобы заполнить и получить массив этих структур для вызывающего. Проблема в том, что я не смог найти подпись RetrieveStuff на управляемой стороне. Я предполагаю, что требуется обычная сортировка? Вот что у меня есть:Передача SAFEARRAY неуправляемых структур между управляемым и неуправляемым кодом

IDL из "SomeLibrary":

[ 
uuid(xxxxx-xxxx-xxxx-xxxx-xxxxx) 
] 
struct MyStructure 
{ 
    [helpstring("Some string values")] SAFEARRAY(BSTR) moValues; 
    [helpstring("Some other value")] BSTR moValue; 
}; 

Неуправляемый код (абонент):

SAFEARRAY* saArray = NULL; 
MyManagedLibPtr->RetrieveStuff(&saArray); // <--This is the key part 

// The rest is just parsing the results. 
// Using SafeArray -wrapper class that handles access/unaccess/etc.. 
SafeArray<SomeLibrary::MyStructure, VT_RECORD> oResults(saArray); 
for (int i =0; i < oResults.GetSize(0); i++) 
{ 
    SomeLibrary::MyStructure oStruct = oResults[i]; 
    // Etc...... 
} 

На стороне C#, я попробовал несколько различных решений, но ни один из они были верны. Это одна была бы слаще, но, очевидно, автоматизация mashalling не было достаточно сладко:

// Interface 
[DispId(123)] 
void RetrieveStuff(ref SomeLibrary.MyStructure[] roResultArray); 

Я получаю ошибку некоторые HRESULT -кода. Не проверял, какой именно, но, очевидно, это вызвано неправильной подписью или сортировкой. Любая помощь?

+1

VT_RECORD не является хорошей идеей для .NET/COM Interop. Просмотрите предыдущую дискуссию об этом здесь: http://stackoverflow.com/questions/16994495/c-interop-embedding-an-array-in-a-udt –

+0

Yup. Код C++ также неверен, использование IRecordInfo является обязательным. Измените структуру на интерфейс с двумя свойствами, и все проблемы исчезнут. –

+0

Вы оба, вероятно, правы, но в моем приложении (около 1 000 000 строк кода) изменение обычно используемой структуры на что-то еще не слишком хорошо. Таким образом, даже если это была не лучшая идея, мне все равно хотелось бы знать, разрешена ли проблема выше даже с пользовательской сортировкой. –

ответ

0

Итак, я нашел ответ, который является ПОЧТИ по запросу. По какой-то причине я не мог заставить его работать с параметром ref, но я смог выполнить сортировку с . Таким образом, это не 100% ответ на проблему, но, черт возьми, близко к ней и, вероятно, поможет и другим.

Правильная декларация интерфейса на управляемом стороне:

// Interface 
[DispId(123)] 
void RetrieveStuff([Out, MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_RECORD)] out SomeLibrary.MyStructure[] roResultArray); 
Смежные вопросы