阅读C结构与"工会"从C#与PInvoke的类型 [英] Reading C structures with "union" types from C# with PInvoke

查看:131
本文介绍了阅读C结构与"工会"从C#与PInvoke的类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想提请托管方(C#)建于C.结构

I'm trying to bring to managed side (C#) a structure built in C.

让我们假设这个结构(C code):

Let's assume this structure (C code):

typedef struct S{
    int i;
    union{
        TypeA a;
        TypeB b;
        TypeC c;
    }uni;
 } S;  

现在,我创建C#包装类:

Now, i create the C# wrapper classes:

[StructLayout(LayoutKind.Explicit)]
public class S
{
    [FieldOffset(0)] 
    public int i;
    [FieldOffset(4)] 
    public TypeA a;
    [FieldOffset(4)]
    public TypeB b;
    [FieldOffset(4)]
    public TypeC c;
}

和我有一个PInvoke的方法来获得信对象:
(C的实现创造与工会领域的类型A返回S结构)

And I have a PInvoke method to get the S object:
(C's implementation create and return a S structure with a TypeA in union field)

[DllImport("Library.dll", CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.S)]
public static extern S getUnionStruct();

在某个地方主要功能,我做的:

Somewhere in main function, I do:

S s = getUnionStruct();
Console.WriteLine("unions type: {0}",(S.a).GetType());

结果是AssembleName.TypeC(???)

The result is "AssembleName.TypeC" (???)

.NET Framework是假设TypeC,因为这是最后的声明。我也注意到,如果TypeC的大小比类型A小我得到无法读取所有类型A领域。

.net Framework is assuming the TypeC because that was the last declared. I also notice that if the size of TypeC is smaller than TypeA I get unable to read all the TypeA fields..

这是从.NET中的错误或我应该做不同的东西?

Is this a bug from .net or I should be doing something different?

推荐答案

现在的问题是如何使用引用类型来包装非托管类型。 当CLR执行的GetType的方法,它使用了一个虚拟表只可含有一种类型的依次在声明覆盖。最后声明场胜(TypeC在这种情况下)
切换类到结构可以解决该问题。

The problem is about using reference types to wrap the unmanaged types. When the CLR executes the "GetType" method, it uses a virtual table which only can contain one type that was successively overridden in declaration. The last declared field wins (TypeC in this case)
Switching the "class" to "struct" resolves the problem.

[StructLayout(LayoutKind.Explicit)]
public struct S
{
    [FieldOffset(0)] 
    public int i;
    [FieldOffset(4)] 
    public TypeA a;
    [FieldOffset(4)]
    public TypeB b;
    [FieldOffset(4)]
    public TypeC c;
}

[StructLayout(LayoutKind.Sequencial)]
public struct TypeA
{
    //...
}

[StructLayout(LayoutKind.Sequencial)]
public struct TypeB
{
    //...
}

[StructLayout(LayoutKind.Sequencial)]
public struct TypeC
{
    //...
}

这篇关于阅读C结构与"工会"从C#与PInvoke的类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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