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

Posted

技术标签:

【中文标题】处理从 C# 服务器返回的 SAFEARRAY【英文标题】:Handling a SAFEARRAY returned from C# server 【发布时间】:2009-10-09 14:59:18 【问题描述】:

我需要将一组结构(类)从 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)。

有什么想法吗?我真的被困在这上面了。

【问题讨论】:

【参考方案1】:

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

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

这成功了。

【讨论】:

【参考方案2】:

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

【讨论】:

以上是关于处理从 C# 服务器返回的 SAFEARRAY的主要内容,如果未能解决你的问题,请参考以下文章

如何读取 C++ SAFEARRAY**,它是 C# 返回值为 byte[] 的 COM 互操作的结果?

如何在 C++ 中创建和初始化双精度的 SAFEARRAY 以传递给 C#

C# 中如何使用 safearray 安全数组

如何实现 SAFEARRAY(long) 参数?

C++ 托管 clr 调用库不在 safearray 参数中返回字符串

SafeArray 的 COM SafeArray