2010-09-02 34 views
9

Phản ứng ruột của tôi là không, bởi vì bộ nhớ được quản lý và không được quản lý là khác biệt, nhưng tôi không chắc liệu .NET Framework có đang làm điều gì đó với Marshaling đằng sau hậu trường hay không.Sẽ thay đổi cấu trúc trong C# ảnh hưởng đến bộ nhớ không được quản lý?

Điều tôi tin là: Khi nhận cấu trúc từ DLL không được quản lý của tôi, nó giống như gọi hàm IntPtr và sau đó sử dụng nó và lớp Marshal để sao chép cấu trúc vào bộ nhớ được quản lý (và thay đổi được thực hiện để cấu trúc trong bộ nhớ được quản lý không bong bóng lên).

Tôi dường như không thể tìm thấy tài liệu này ở bất cứ đâu trên MSDN. Bất kỳ liên kết nào cũng sẽ được đánh giá cao.

Đây là những gì mã của tôi trông giống như:

[DllImport("mydll.dll", BestFitMapping=false, CharSet=CharSet.Ansi)] 
private static extern int GetStruct(ref MyStruct s); 

[StructLayout(LayoutKind.Sequential, Pack=0)] 
struct MyStruct 
{ 
    public int Field1; 
    public IntPtr Field2; 
} 

public void DoSomething() 
{ 
     MyStruct s = new MyStruct(); 
     GetStruct(ref s); 

     s.Field1 = 100; //does unmanaged memory now have 100 in Field1 as well? 
     s.Field2 = IntPtr.Zero; //does unmanaged memory now have a NULL pointer in field Field2 as well? 
} 

Trả lời

0

CSharp Ngôn ngữ Specification.doc pg 26

constructors Struct được gọi với các nhà điều hành mới, nhưng điều đó không có nghĩa bộ nhớ đang được phân bổ. Thay vì phân bổ động một đối tượng và trả về một tham chiếu đến nó, một hàm tạo struct chỉ đơn giản trả về giá trị struct (thường ở vị trí tạm thời trên ngăn xếp), và giá trị này sau đó được sao chép khi cần thiết.

Vì, không có gì đặc biệt về cửa hàng sao lưu 'cấu trúc', vì vậy người ta sẽ không mong đợi có các hoạt động thắt chặt đồng nghĩa diễn ra phía sau nhiệm vụ thành viên.

+0

Tôi nghĩ đây là câu trả lời đúng. Thực tế là không có gì móc vào cấu trúc (hoặc các trường của nó) để thay đổi trở lại bộ nhớ không được quản lý khi các trường của nó được thay đổi dường như kết luận trả lời câu hỏi này một cách dứt khoát. – userx

8

Không, P/Gọi marshaller sao chép các giá trị viên cấu trúc không được quản lý vào phiên bản quản lý của cấu trúc. Nói chung, phiên bản được quản lý của cấu trúc không tương thích với phiên bản không được quản lý của nó. Không thể phát hiện bố cục bộ nhớ, điều CLR sử dụng để sắp xếp lại các trường để làm cho cấu trúc nhỏ hơn. Marshaling là điều cần thiết, bạn để tạo bản sao.

Không thể sửa đổi cấu trúc bằng chữ ký chức năng đã cho vì bạn cho phép điền vào bộ nhớ được chuyển cho nó. Bản thân hàm đã sao chép cấu trúc. Tuy nhiên, bạn có thể bên trên giá trị Field2 vì nó là một con trỏ thô. Nếu điều đó trỏ đến một cấu trúc thì hãy tự sắp xếp nó với Marshal.PtrToStructure(). Sửa đổi bản sao được quản lý của nó và sao chép nó trở lại bộ nhớ không được quản lý với Marshal.StructureToPtr(). Hoặc truy cập trực tiếp với Marshal.ReadXxx() và WriteXxx().

+0

Đây là những gì tôi mong đợi, nhưng tôi thực sự đang tìm kiếm một số loại xác nhận điều này trên MSDN hoặc tương tự. Ngoài ra, một gói = 0 chỉ là tốt (nó chỉ có nghĩa là nền tảng mặc định và là quan trọng để sử dụng cho x86 và x64 triển khai với cùng một mã). Xem: http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.structlayoutattribute.pack.aspx – userx

+1

Đây thực sự không phải là một nơi tốt để tìm liên kết, tôi khuyên bạn nên google. –

+0

Việc khôi phục những gì tôi đã nói trong câu hỏi của tôi cũng không thực sự là câu trả lời :). Tôi hy vọng cho một số loại tài liệu giải thích hành vi như được thực hiện bởi Microsoft. – userx

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