将结构数组从 .NET 编组到 C++:何时进行复制?
考虑像 System.Drawing.Point 这样的结构 - 具有 LayoutKind.Sequential 并且仅包含原始成员的结构。我有一个此类结构的 C# 数组。
我通过 P/Invoke 将其传递给(非托管)C++ 函数。在 C++ 方面,有相应的结构定义(例如 struct Point { int x, y; }; )。该函数采用 Point*
参数。
我的问题是,在什么情况下 CLR 会复制数据,在什么情况下它只是固定数据?变量包括:
- 数组类型:一维或矩形
- C# 函数定义 - 使用
Point*
或Point[]
/Point[,]
- 使用
fixed(Point*pointer = array)
或不使用
我想避免复制,因为它很慢。
Consider a struct like System.Drawing.Point - one with LayoutKind.Sequential and containing only primitive members. I have a C# array of such structs.
I'm passing it to an (unmanaged) C++ function via P/Invoke. On the C++ side there's a corresponding definition of the struct (e.g. struct Point { int x, y; };
). The function takes a Point*
arg.
My question is, in what cases does the CLR copy the data and in what cases does it just pin it? Variables include:
- Array type: one-dimensional or rectangular
- C# definition of the function - using
Point*
orPoint[]
/Point[,]
- using
fixed(Point* pointer = array)
or not
I want to avoid the copying because it's slow.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我在固定方面没有太多经验,但是根据我对 MSDN 的阅读,您的结构应该被固定而不是复制。相关参考文献:
来自#2:
并且您的 Point 结构在 #3 中作为示例给出,因此它符合 blittable 类型。
我注意到固定对象的一些开销 此处,但那是针对
固定字节[]
,这可能与您的不同点[]
。I don't have much experience with pinning, but, according to my reading of MSDN, your structs should be pinned and not copied. Relevant refs:
From #2:
And your Point struct is given as an example in #3, so it qualifies as a blittable type.
I noticed some overhead to pinning objects here, but that was for a
fixed byte[]
, which may be different to yourPoint[]
.结构体按值引用,类按引用引用。
这意味着你总是有一个结构体,并且你进行赋值,它的值会被复制,就像你使用 int a = b; 时一样。 a 具有 b 的值,而不是指向 b,因此如果更改 a 的值,b 将不会更新。
如果你有一个数组,它在内部存储一个默认向量、类的指针和结构的结构默认值。请注意,如果结构包含引用类型(类)的成员,则会存储设置为 null 的指针。
假设您
在打印值时因为 Point 是一个结构体(值类型)
对于 C++,您可以使用 foo(Point *pa) 或 foo(Point[] pa) 获得相同的结果;在 C# 中,在一维数组中使用 foo(Point[] pa) 。对于 C++ 中的矩形 foo(Point **pa) 和 C# 中的 foo(Point[][])
Structs are referenced by value and Classes are referenced by reference.
It means always you have a struct and you make an assignment its values are copied, like when you use int a = b; a has the value of b and not point so b so if you change the value of a, b will not be updated.
If you have an array, internally it stores a vector of defaults, pointers for classes and the default value of structure for structs. Notice that if the struct contains a member which is a reference type (class) a pointer set to null is stored.
Supose you have
Since Point is a struct (value type) when you print the values
For C++ you can use foo(Point *pa) or foo(Point[] pa) for same results; in C# use foo(Point[] pa) in single dimension array. For a rectangular foo(Point **pa) in C++ and foo(Point[][]) in C#