Не удается заставить SAFEARRAY работать с Interop

У меня есть COM-сервер ATL, где метод интерфейса

STDMETHODIMP CWrapper::RUN(long iDataSize, SAFEARRAY** iData)

и MIDL для этой функции выглядит так

[id(1), helpstring("method RUN")] HRESULT RUN([in] long nSize, [in, size_is(nSize)] SAFEARRAY(_MyDataType*)* iData);

Я импортирую tlb из этого проекта с помощью tlbimp, поэтому я могу использовать собственные массивы. Затем я вызываю его из С# следующим образом

 m_ServerWrapper.RUN(iInputs.Length,ref iInputs)

где Inputs уже выделен и заполнен другим COM-объектом из моей программы на C#. Теперь, когда я вызываю оболочку C++, у меня есть BadPtr для моего безопасного массива, и вызов последующего COM-объекта из CWrapper::RUN терпит неудачу, и массив не попадает в окончательную dll. Он отображается как нераспределенный. Кто-нибудь знает, что я делаю неправильно? Спасибо

РЕДАКТИРОВАТЬ: я должен был сказать, что массив отлично выглядит на С#.

РЕДАКТИРОВАТЬ 2: Отладчик показывает безопасный массив iData из IDispatch* = 0x0000000 <Bad Ptr>, 5, 0x0000000 <Bad Ptr>({lpvtbl = 0xblahblah},.... Так что, похоже, часть моей информации попадает туда.


person Steve    schedule 27.03.2009    source источник
comment
Определен ли _MyDataType в IDL? Если нет, то вы должны сделать это там. Другое дело: зачем вам nSize? SAFEARRAY поддерживает собственный размер.   -  person HS.    schedule 08.04.2009


Ответы (1)


Обычный массив C# — это не то же самое, что SAFEARRAY. Я думаю, что вы должны сделать свой собственный:

[StructLayout(LayoutKind.Sequential)]
struct SafeArray
{
    public ushort   dimensions;  
    public ushort   features;    
    public uint     elementSize; 
    public uint     locks;       
    public IntPtr   dataPtr;     
    public uint     elementCount;
    public int      lowerBound;  
}

Затем используйте Marshal.AllocCoTaskMem() для создания памяти. Заполните все данные, а затем передайте их.

person i_am_jorf    schedule 27.03.2009
comment
Все документы, которые я могу найти, указывают, что уровень взаимодействия должен маршалировать массив в безопасный массив. - person Steve; 28.03.2009