与C#结合的元素C ++结构 [英] Marshal a C++ structure with union to C#

查看:114
本文介绍了与C#结合的元素C ++结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

阅读编组时,我认为以下内容有效,但编组失败了。 C ++定义如下:

Reading up on marshaling, I thought the following would be valid but the marshaling fails. The C++ definition is as follows:

typedef struct
{
    char* t;
    size_t t_length;
    double d;
} A;

typedef struct
{
    char* t;
    size_t t_length;
    char* k;
    size_t k_length;
} B;

typedef struct
{   
    char* id;
    size_t id_length;
    int enumOfType;
    union
    {
        A typeA;
        B typeB;
    }
} NofAB



我已经按如下方式定义了C#类:


I've defined the C# classes as follows:

[StructLayout(LayoutKind.Sequential)]
public class A
{
    public string t;
    public IntPtr tLength;  // IntPtr is the only thing that maps correctly in x86/x64
    public double d;
};

[StructLayout(LayoutKind.Sequential)]
public class B
{
    public string t;
    public IntPtr tLength;
    public string k;
    public IntPtr kLength;
};

[StructLayout(LayoutKind.Explicit)]
public class ABUnion
{
    [FieldOffset(0)]
    public A TypeA;
    [FieldOffset(0)]
    public B TypeB;
}

[StructLayout(LayoutKind.Sequential]
public class NofAB
{
    public string id;
    public IntPtr idLength;
    public int enumOfType;
    public ABUnion AOrB;  
}



当我尝试使用NofAB封送PtrToStructure时,我在ABUnion上得到一个LoadTypeException。这是一个简化的例子,我真的有5种可能类型的联合,但我不想放置所有代码。

任何人都可以向我解释为什么这不起作用?我该怎么做才能使它工作?

谢谢。


When I attempt to marshal PtrToStructure using NofAB, I get a LoadTypeException on ABUnion. This is a simplified example where I really have a union of 5 possible types but I didn't want to put all that code in place.
Can anyone explain to me why this doesn't work? What can I do to make it work?
Thanks.

推荐答案

C ++联合可以在.NET中匹配通过使用 [FieldOffset] 成员属性创建的布局, System.Runtime.InteropServices.FieldOffsetAttribute 。请参阅:

http://msdn.microsoft.com/en-我们/库/ system.runtime.interopservices .fieldoffsetattribute.aspx [ ^ ]。



上面引用的MDSN文章中的代码示例清楚地显示了如何使用该属性,但是您可能需要了解如何使用该属性模仿联盟。以下是如何:在联合的情况下,参与不同联合案例的成员相对于结构的起始采用相同的地址。因此,使用 [FieldOffset] ,您必须为表示联合成员的两个不同成员指定相同的偏移量。在您的情况下,成员 A B 应该在相同的偏移量,您可以考虑成员计算结构的布局(由32位,16位或8位边界对齐)和先前成员按顺序采用的存储器。我建议在结构的所有先前成员中使用此属性,以确定。



-SA
C++ unions can be matched in .NET by the layouts created using [FieldOffset] member attribute, System.Runtime.InteropServices.FieldOffsetAttribute. Please see:
http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.fieldoffsetattribute.aspx[^].

The code sample in the MDSN article referenced above clearly shows how to use the attribute, but perhaps you need an idea on how to mimic the union. Here is how: in case of union, members participating in different cases of union take identical addresses relative to the starting of the structure. Hence, with [FieldOffset], you will have to specify the same offset to two different members representing members of the union. In your case, the members A and B should be at the same offset, which you can calculate taking into consideration member layout of the structure (aligned by 32-bit, 16-bit or 8-bit boundary) and memory taken by the previous members in sequential order. I would advice to use this attribute on all previous members of the structure, for certainty.

—SA

这篇关于与C#结合的元素C ++结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆