如何在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实例,然后将其地址分配给LowLeft
和TopRight
字段?
一些错误的方法:
-
直接使用C#new关键字是语法错误:
r.LowLeft =新的点();
-
使用虚拟变量似乎当我们离开的范围是错误的,因为它是在堆上分配的,因而被释放:
VAR哑=新的点(); r.LowLeft = @dummy;
答
说到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
字段阻止您使用此声明,但值得放在后面。
可能的重复https://stackoverflow.com/questions/4853213/are-structs-always-stack-allocated-or-sometimes-heap-allocated –
@Sinatr这个问题与你提到的不一样。 – melmi
@丹瑞森这个问题是相关的,但不相同。我知道哪里可以分配一个结构。但这不是重点。我真正想要的是一个指向该结构的指针。 – melmi