从C++传递一个自定义类型的Safearray到C#

6
如何使用 Safearray 将自定义类型的数组(仅包含属性的类)从 C++ 传递到 C#?使用 VT_RECORD 类型是否是正确的方法?
我正在尝试以下方式,但当尝试填充 safearray 时,SafeArrayPutElement 返回错误 类数组的引用以 NULL 的形式传递到托管代码。
在托管世界中,我有类似以下的代码:
[ComVisible(true)]
public interface IStatistics
{
    double Mean { get; set; } 
    double StdDev { get; set; } 
}

[Serializable]
[ComVisible(true)]
public class Statistics : IStatistics
{
    public Mean { get; set; }
    public double StdDev { get; set; } 
}

非托管世界:

HRESULT hr = CoInitialize(NULL);
...
SAFEARRAY *pEquationsStatistics;

// common dimensions for all arrays
SAFEARRAYBOUND dimensions[1];  
dimensions[0].cElements = 2;   
dimensions[0].lLbound = 0;    

pEquationsStatistics = SafeArrayCreate(VT_RECORD, 1, dimensions);
...

for (long i = 0; i < dimensions[0].cElements; i++)
{
    long indices[1];
    indices[0] = 0;

    ... 

    // Equation statistics
    IStatisticsPtr pIStatistics(__uuidof(Statistics)); 
    pIStatistics->PutMean(1.0); // so far so good

    result = SafeArrayPutElement(pEquationsStatistics, indices, pIStatistics);

    ...
    indices[0]++;
}

请注意,我可以使用SafeArray来传递其他BSTR数组,这两个应用程序之间没有问题。因此,这是传递结构的特殊情况。
1个回答

4
我不确定我是否正确理解了你的问题,但也许你需要使用VT_DISPATCH?如果你想让它与VT_RECORD一起工作,那么你的结构体应该实际上是一个结构体(而不是类),并且还需要[StructLayout(LayoutKind.Sequential)]属性。 编辑:你最初收到的错误可能是DISP_E_BADINDEX吗?你的代码中indices具体是什么?它包含什么?(你知道SafeArrayPutElement的签名要求它是一个指针,对吧?)

只要能完成工作,对我来说什么都可以;)仅从名称来看,VT_RECORD似乎是最接近我想要实现的选项。我只需要能够将这个结构/类公开给非托管代码以填充它。 - Stefano Ricciardi
你能详细说明一下你当前的解决方案是如何失败的吗?是否有错误信息? - fretje
实际上,指向类数组的引用是 null。 - Stefano Ricciardi
这对我来说看起来不错...你尝试过VT_DISPATCH吗?或者将类改为结构体?否则,我想我不能再帮忙了 :( - fretje
我刚刚尝试了VT_DISPATCH,看起来它解决了问题。非常感谢! - Stefano Ricciardi
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接