Не могу заставить SAFEARRAY работать с Interop - PullRequest
1 голос
/ 28 марта 2009

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

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, поэтому я могу использовать собственные массивы. Затем я вызываю его из C # следующим образом

 m_ServerWrapper.RUN(iInputs.Length,ref iInputs)

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

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

EDIT2: отладчик показывает iData safearray IDispatch* = 0x0000000 <Bad Ptr>, 5, 0x0000000 <Bad Ptr>({lpvtbl = 0xblahblah},.... Похоже, что часть моей информации попадает туда.

1 Ответ

0 голосов
/ 28 марта 2009

Обычный массив 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 () для создания памяти. Заполните все данные и затем передайте их.

...