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

发布于 2024-07-24 06:31:11 字数 1295 浏览 11 评论 0原文

如何使用 Safearray 将自定义类型数组(仅包含属性的类)从 C++ 传递到 C#? 使用 VT_RECORD 类型是正确的方法吗?

我正在尝试以下方式,但是 SafeArrayPutElement 在尝试填充 safearray 时返回错误,对类数组的引用作为 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 的其他数组,两者之间没有问题应用程序。 所以这是传递结构所特有的事情。

斯特凡诺

how can one use a Safearray to pass an array of custom types (a class containing only properties) from C++ to C#? Is using the VT_RECORD type the right way to do it?

I am trying in the following way, but SafeArrayPutElement returns an error when trying to fill the safearray the reference to the array of classes gets to the managed code as a NULL.

I have something like the following in the managed world:

[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; } 
}

Unmanaged world:

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]++;
}

Please note that the I am able use the SafeArray to pass other arrays of BSTR with no problems between the two applications. So this is something peculiar to passing a structure.

Stefano

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

冷清清 2024-07-31 06:31:11

我不太确定我是否正确理解你的问题,但也许你需要VT_DISPATCH
我认为如果您希望它与 VT_RECORD 一起使用,那么您的结构实际上应该是一个结构(而不​​是类)并且还需要 [StructLayout(LayoutKind.Sequential)]属性。

编辑:您首先遇到的错误是否是DISP_E_BADINDEX? 代码中的索引到底是什么? 它包含什么? (您知道 SafeArrayPutElement 要求它是一个指针,对吧?)

I'm not really sure if I understand your question right, but maybe you need VT_DISPATCH?
I think if you want it to work with VT_RECORD, then your struct should actually be a struct (not a class) and also needs the [StructLayout(LayoutKind.Sequential)] attribute.

Edit: Can it be that the error you first got was DISP_E_BADINDEX? What exactly is indices in your code? What does it contain? (You know that the signature of SafeArrayPutElement requires it to be a pointer, right?)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文