2011-12-16 33 views
7

Hãy xem xét một cấu trúc như System.Drawing.Point - một với LayoutKind.Sequential và chỉ chứa các thành viên nguyên thủy. Tôi có một mảng C# của các cấu trúc như vậy.Mảng hỗn hợp của các cấu trúc từ .NET đến C++: khi nào nó sao chép?

Tôi chuyển nó sang hàm C++ (không được quản lý) qua P/Invoke. Ở phía C++ có định nghĩa tương ứng về cấu trúc (ví dụ: struct Point { int x, y; };). Hàm này mất Point* arg.

Câu hỏi của tôi là, trong trường hợp nào CLR sao chép dữ liệu và trong trường hợp nào nó chỉ cần ghim nó? Biến bao gồm:

  • loại mảng: một chiều hoặc hình chữ nhật
  • C định nghĩa # của hàm - sử dụng Point* hoặc Point[]/Point[,]
  • sử dụng fixed(Point* pointer = array) hay không

Tôi muốn tránh sao chép vì nó chậm.

+0

Nó không phải là tài liệu, mảng đơn giản chỉ được ghim. Sử dụng trình gỡ rối trong trường hợp nghi ngờ, gõ '* & array' để lấy địa chỉ mảng trong C#. Và so sánh với giá trị con trỏ bạn nhận được trong mã gốc. +8 ở chế độ 32 bit. –

Trả lời

0

Cấu trúc được tham chiếu theo giá trị và Lớp được tham chiếu theo tham chiếu.

Điều đó có nghĩa là bạn luôn có cấu trúc và bạn thực hiện một nhiệm vụ giá trị của nó được sao chép, như khi bạn sử dụng int a = b; a có giá trị b và không phải điểm b nên nếu bạn thay đổi giá trị a, b sẽ không được cập nhật.

Nếu bạn có một mảng, bên trong nó lưu trữ một vectơ mặc định, con trỏ cho các lớp và giá trị mặc định của cấu trúc cho cấu trúc. Lưu ý rằng nếu cấu trúc chứa một thành viên là một kiểu tham chiếu (lớp) thì một con trỏ được đặt là null được lưu trữ.

Giả sử bạn có

Point p = new Point(0, 1); 
Point[] pa = new Point[10]; 
pa[0] = p; 
++p.X; 

Từ Point là một struct (kiểu giá trị) khi bạn in các giá trị

p: {1, 1} 
pa[0]: {0, 1} 
pa[1-9]: {0, 0} 

Đối với C++ bạn có thể sử dụng foo (Point * pa) hoặc foo (Point [] pa) cho cùng một kết quả; trong C# sử dụng foo (Point [] pa) trong mảng kích thước đơn. Đối với một hình chữ nhật foo (Điểm ** pa) trong C++ và foo (Điểm [] []) trong C#

+0

Điều này không thực sự trả lời câu hỏi ... –

2

Tôi không có nhiều kinh nghiệm với ghim, nhưng, theo đọc của tôi về MSDN, cấu trúc của bạn nên được ghim và không được sao chép. bố trí

định dạng lớp blittable đã cố định (định dạng) và đồng: refs liên quan:

  1. Marshalling data with PInvoke
  2. Copying and pinning
  3. Blittable and non-blittable types
  4. Default marshalling for value types

Từ # 2 biểu diễn dữ liệu mmon trong cả bộ nhớ được quản lý và không được quản lý. Khi các kiểu này yêu cầu marshaling, một con trỏ tới đối tượng trong heap được truyền trực tiếp đến callee.

Và cấu trúc điểm của bạn được đưa ra làm ví dụ ở # 3, vì vậy, nó đủ điều kiện như một loại blittable.

Tôi nhận thấy một số chi phí để ghim các đối tượng here, nhưng đó là số fixed byte[], có thể khác với Point[] của bạn.

Các vấn đề liên quan