处理从C#服务器返回的SAFEARRAY

时间:2009-10-09 14:59:18

标签: c# c++ com interop

我需要将一个结构(类)数组从C#库返回到非托管C ++客户端。这是C#库中的函数:

[ComVisible(true)]
[Serializable]
public sealed class RetrieverProxy : IRetrieverProxy
{
    public IMyRecord[] RetrieveMyRecords(long[] ids)
    {
        IList<IMyRecord> result = new List<IMyRecord>();
        for (int i = 0; i < ids.Count(); i++)
        {
            result.Add(new MyRecord()
            {
              // some test data
            });
        }

        return result.ToArray();
    }
 }

MyRecord本身包含一组结构,这些结构也是COM可见的,包含一个double和一个DateTime字段。

我从regasm获得以下包装:

inline SAFEARRAY * IRetrieverProxy::RetrieveMyRecords (SAFEARRAY * ids) {
    SAFEARRAY * _result = 0;
    HRESULT _hr = raw_RetrieveMyRecords(ids, &_result);
    if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
    return _result;
}

从客户端代码中,我调用了以下库:

SAFEARRAY *pMyRecordsSA;
SAFEARRAY *pIds;
// omitting pIds initialization, because from the library I can see 
// that they are ok
pMyRecordsSA = pIRetrieverProxy->RetrieveMyRecords(pIds);

我遇到的问题是如何检索现在存储在pMyRecordsSA中的结果。我尝试了以下但是我没有工作:

    IMyRecordPtr pIMyRecords(__uuidof(MyRecord));
    HRESULT hr = SafeArrayAccessData(pMyRecordsSA, (void**)&pIMyRecords);

但是然后尝试使用pIMyRecords指针会导致访问冲突(hr为0K)。

有什么想法吗?我真的很困惑。

2 个答案:

答案 0 :(得分:2)

事实证明,我只需要“另一层次的间接”。也就是说,指向指针的指针与简单的指针。

IMyRecords** pIMyRecords; 
HRESULT hr = SafeArrayAccessData(pMyRecordsSA, (void**)&pIMyRecords);

这就是诀窍。

答案 1 :(得分:0)

看看CComSafeArray它可能会为您节省一些时间。