无法让SAFEARRAY与Interop合作

时间:2009-03-27 21:42:55

标签: c# c++ interop atl

我有一个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);

我使用tlbimp从这个项目导入tlb,所以我可以使用本机数组。然后我从C#中调用它,如下所示

 m_ServerWrapper.RUN(iInputs.Length,ref iInputs)

其中Input已经分配并填充了我的C#程序中的另一个COM对象。现在,当我调用C ++包装器时,我的safearray有一个BadPtr,来自CWrapper::RUN的后续COM对象的调用失败,数组没有进入最终的dll。它显示为未分配。有没有人知道我做错了什么?感谢

编辑:我应该声明数组在C#中看起来很好。

EDIT2:调试器显示iData的{​​{1}}安全阵列。 所以看起来我的一些信息就到了那里。

1 个答案:

答案 0 :(得分:0)

普通的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()创建内存。填写所有数据然后传递。