IJW:托管代理结构?

时间:2009-05-18 17:47:00

标签: .net unmanaged marshalling

我正在努力将一些C ++代码移植到托管.NET。我需要以原生形式保留一些C ++代码,并尝试使用IJW方法。我知道可以声明一个非托管结构,以便它可以正确编组到.NET代码,但C ++编译器似乎没有这样做。

例如,我有这个代码(托管):

struct MyStruct
{
     int some_int;
     long some_long;
};

public ref class Class1
{
    static MyStruct GetMyStruct()
    {
        MyStruct x = { 1, 1 };
        return x;
    }
};

它编译,但当我使用反射器查看它时,代码看起来像这样:

public class Class1
{
    // Methods
    private static unsafe MyStruct GetMyStruct()
    {
        MyStruct x;
        *((int*) &x) = 1;
        *((int*) (&x + 4)) = 1;
        return x;
    }
}

[StructLayout(LayoutKind.Sequential, Size=8), NativeCppClass, 
                      MiscellaneousBits(0x41), DebugInfoInPDB]
internal struct
{
}

基本上,MyStruct中没有字段对.NET可见。有没有办法让C ++编译器生成一个?

在回答时,请考虑这个:我知道如何创建.NET框架可见的托管类。我对此并不感兴趣。我想要的是C ++编译器以.NET将理解它的方式声明非托管结构,如:

[StructLayout(LayoutKind::Sequential, blablabla ... )]
struct MyStruct
{
    [MarshalAs ....... ]
    System::Int32 some_int;
    [MarshalAs ....... ]
    System::Int32 some_long;
};

2 个答案:

答案 0 :(得分:1)

如果要从C ++托管代码定义.NET应用程序可见的公共结构,可以使用以下方法(请注意'public'和'value'关键字):

[StructLayout(LayoutKind::Sequential)]
public value struct MyStruct
{
    int some_int;
    long some_long;
};

如果希望在C#和C / C ++之间移动非托管结构,则必须在双方都声明它。像这样在C:

struct MyUnmanagedStruct
{
         int some_int;
         long some_long;
};

并且喜欢这样,例如,在C#中,例如:

[StructLayout(LayoutKind.Sequential)]
struct MyUnmanagedStruct
{
    public int some_int;
    public long some_long; // or as int (depends on 32/64 bitness)
};

您必须确保.NET中的字段与C中的字段匹配。您可能希望使用StructLayout属性(特别是Pack)。请参阅此处的两个教程:Structs Tutorial和此处:How to: Marshal Structures Using PInvoke

答案 1 :(得分:1)

这个问题在过去两年中被观看了194次,并不缺乏关注。把缺乏答案作为足以证明这是不可能的。非托管结构具有被封送,结构的.NET布局规则与C或C ++编译器的.NET布局规则根本不兼容。 This answer提供了有关.NET如何以这种方式工作的背景信息。