如何在C#中实例化堆中的结构

问题描述:

我正在接受一个C DLL,它接受嵌套的尖端结构形式的参数。它简化了C#的形式是这样的:如何在C#中实例化堆中的结构

struct Point 
{ 
    public double X; 
    public double Y; 
} 

struct Rectangle 
{ 
    public unsafe Point* LowLeft; 
    public unsafe Point* TopRight; 
} 

的问题是,当我想要实例结构Rectangle。如何在堆上创建一个Point实例,然后将其地址分配给LowLeftTopRight字段?

一些错误的方法:

  • 直接使用C#new关键字是语法错误:

    r.LowLeft =新的点();

  • 使用虚拟变量似乎当我们离开的范围是错误的,因为它是在堆上分配的,因而被释放:

    VAR哑=新的点(); r.LowLeft = @dummy;

+0

可能的重复https://stackoverflow.com/questions/4853213/are-structs-always-stack-allocated-or-sometimes-heap-allocated –

+0

@Sinatr这个问题与你提到的不一样。 – melmi

+0

@丹瑞森这个问题是相关的,但不相同。我知道哪里可以分配一个结构。但这不是重点。我真正想要的是一个指向该结构的指针。 – melmi

说到M.Elmi在评论中说过的话,我已经将结构放入非托管内存中了。不幸的是,我不知道如何检查,它是在堆或堆栈或诸如此类的东西,但它肯定坐在现在非托管内存...

static void Main(string[] args) 
    { 
     SuperStruct myStruct = new SuperStruct() { MyName = "Dan", MyNumber = 1 }; 
     SuperStruct myOtherStruct; 

     IntPtr pointer = Marshal.AllocHGlobal(Marshal.SizeOf<SuperStruct>()); 

     Marshal.StructureToPtr(myStruct, pointer, false); 

     myOtherStruct = Marshal.PtrToStructure<SuperStruct>(pointer); 

     Console.WriteLine($"Name: {myOtherStruct.MyName}, Number: {myOtherStruct.MyNumber}."); 
     Console.ReadLine(); 
    } 
    struct SuperStruct 
    { 
     public int MyNumber; 
     public string MyName; 
    } 

总体而言,其过程是:1)设置一些非托管内存准备通过使用Marshal.AllocHGlobal来包含数据。 2)使用Marshal.StructureToPtr方法设置该内存。 3)使用Marshal.PtrToStructure<T>方法从非托管内存中检索该结构。

它也被指出(由M.Elmi在评论),我们可以宣布一个类型的指针,只要有不包含在结构定义的托管类型,像这样:

 unsafe 
     { 
      SuperStruct* ptr = (SuperStruct*)pointer.ToPointer(); 
     } 

在我的具体示例中,string字段阻止您使用此声明,但值得放在后面。

+0

请指出结构指针可以简单地由'SuperStruct * ptr =(SuperStruct *)pointer.ToPointer();' – melmi

+0

@ M.Elmi构建。当我在某处添加'SuperStruct *'时,它给我一个编译器错误'不能取得地址,获取大小或者声明一个指向托管类型的指针('Program.SuperStruct')'它甚至不会用不安全标志进行编译:( –

+1

恕我直言,这是因为字符串字段在你的'struct'中。'string's是托管类,当进入'unsafe'字段时会导致问题。 – melmi