考虑像System.Drawing.Point这样的结构 - 一个使用LayoutKind.Sequential并且只包含原始成员的结构.我有一个这样的结构的C#数组.
我通过P/Invoke将它传递给(非托管)C++函数.在C++方面,有一个相应的结构定义(例如struct Point { int x, y; };).该函数采用Point*arg.
我的问题是,在什么情况下CLR复制数据,在什么情况下它只是固定它?变量包括:
Point*或Point[]/Point[,]fixed(Point* pointer = array)与否我想避免复制,因为它很慢.
长话短说,我将提供一个简单的例子,它可能有用:
public struct Vector3f {
public float x;
public float y;
public float z;
public unsafe float this[int index] {
get {
// Get "p" somehow, so that it points to "this"...
return p[index];
}
set {
// Get "p" somehow, so that it points to "this"...
p[index] = value;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我猜你有我的观点:
var v = new Vector3f();
Assert(v.x == v[0]);
Run Code Online (Sandbox Code Playgroud)
编辑1:
对于那些仍然问:)
Assert(v.y == v[1]);
Assert(v.z == v[2]);
Run Code Online (Sandbox Code Playgroud)
编辑2:
这会fixed产生多余的开销吗?或者这个结构可能已经修复,因此fixed在这里没有效果,只需要满足编译器的需要?可能的答案.
特别是,我正在考虑这样的场景:
unsafe struct Foo
{
public int Bar;
public Foo* GetMyAddr()
{
fixed (Foo* addr = &this)
return addr;
}
}
Run Code Online (Sandbox Code Playgroud)
假设存储在非托管内存中的Foo,我试图找出在GetMyAddr中评估fixed语句所涉及的内容.我知道作为程序员,这个结构永远不会在托管堆上,我只需要以最有效的方式在非托管内存中获取它的地址.如果在这里使用任何锁定或原子操作,我会特别担心,因为这会使它完全不合适.