2010-06-29 42 views
5

Trong dự án C#, tôi cần chuyển các tham số đối tượng bằng cách đặt tham chiếu trong cấu trúc. ví dụ: Tôi có một cấu trúc thông qua với một điều phốiChuyển đổi từ void * sang đối tượng trong C#

struct SOMESTRUCT 
{ 
    public int lpObject; 
} 

đâu lpObject giữ một con trỏ đến một đối tượng tùy chỉnh như

class SomeClass 
{ 
    private string foo; 
} 

Và cấu trúc SOMESTRUCT được chuyển từ phương pháp phương pháp để cuối cùng đạt được mã của tôi. Tôi không thể thay đổi dòng chảy thực hiện cũng không phải là hệ thống SOMSTRUCT lạ, nên tôi đoán giải pháp duy nhất là để đúc tượng của tôi đến một con trỏ như thế này:

var myObject = new SomeClass(); 
GCHandle GC = GCHandle.Alloc(myObject, GCHandleType.Pinned); 
int myRef = GC.AddrOfPinnedObject().ToInt32(); 
GC.Free(); 

SOMESTRUCT struct; 
struct.lpObject = myRef; 
someMethod(struct); 

Tuy nhiên, tôi không thể tìm ra cách để lấy các thành viên myObject từ các trường lpObject. Một cái gì đó như thế này:

SomeClass myObject = CastPointerToObject(struct.myRef) as SomeClass; 

Có cách nào để thực hiện hoặc không thể? Làm thế nào tôi có thể nói với bộ thu gom rác để xử lý đối tượng? Tôi có nên tạo một đối tượng Thu gom rác mới và sao chép trường dữ liệu theo trường không?

TYIA,

+0

sử dụng IntPtr thay vì int ....vì vậy nó sẽ hoạt động trong 64bit cũng như –

Trả lời

4

no No NO NONO !!!

này

struct SOMESTRUCT 
{ 
    public SomeClass object_ref; 
} 

có phải là cách đúng để lưu trữ một tham chiếu trong một cấu trúc.

Mã bạn đã viết và câu trả lời được chấp nhận là 100% bị hỏng.

Địa chỉ trả về GC.AddrOfPinnedObject(GCHandle) chỉ hợp lệ trong khi GCHandle vẫn còn nguyên. Bạn không được gọi số GCHandle.Free và bạn không được để số GCHandle được thu thập. Trong mã của bạn, địa chỉ này đã vô nghĩa trước khi bạn lưu trữ nó.

Nhưng bạn nên để .NET quản lý con trỏ trong khi thu thập rác, bằng cách sử dụng một biến kiểu tham chiếu. Sau đó, bạn không cần phải nhảy qua hoops. Lý do duy nhất để lấy địa chỉ của một đối tượng được quản lý là khi chuyển nó tới một hàm DLL gốc có sẵn, nó sẽ lưu con trỏ sau khi nó trả về. Ví dụ, nó cần thiết với các mảng đệm OpenGL. Nó không cần thiết, bao giờ hết, khi gọi các phương thức C# khác.

Nếu SOMESTRUCT thực sự là một kiểu dữ liệu gốc được sử dụng bởi một số chức năng DLL mà bạn chưa đề cập, thì bạn sẽ cần phải đảm bảo giữ cho số sống GCHandle còn sống. Chỉ miễn là GCHandle tồn tại thì con trỏ bạn vẫn còn hợp lệ.

+0

Đồng ý. Câu trả lời được chấp nhận là không chính xác; tuy nhiên tôi nghĩ rằng có nhiều câu chuyện mà chúng ta không biết, nếu không, tại sao tất cả các công việc phụ khi thời gian chạy sẽ quản lý marshalling một cách chính xác? – codekaizen

+0

@codekaizen: Có, yêu cầu "loại SOMESTRUCT không thể thay đổi" phải có một số lý do mà chúng tôi cần biết để giải quyết chương trình đúng cách. –

+0

Loại SOMESTRUCT là một cấu trúc thông điệp cửa sổ có "con trỏ tùy chỉnh". Con trỏ này ban đầu được sử dụng (trong chương trình) để tham chiếu các chuỗi chứa các đối tượng được tuần tự hóa, hoạt động (loại) tốt. Trong mã của tôi, một số lớp không được tuần tự hóa nên tôi phải đưa ra một giải pháp khác. Trong thực tế, giải pháp được chấp nhận có vẻ OK nhưng chưa bao giờ được thử nghiệm, vì nó đã nêu ra nhiều vấn đề hơn mà nó đã giải quyết; vì vậy tôi đã từ bỏ "con trỏ/serialization" điều và sử dụng một cách C# -ish làm việc. – slaphappy

2

Bạn có muốn đưa con trỏ được trả về trở lại cấu trúc không?

Tương tự như:

lvHitTestInfo = (LVHITTESTINFO)Marshal.PtrToStructure(lP, typeof(LVHITTESTINFO)); 

đâu lvHitTestInfo là một cấu trúc và lp một con trỏ.

Hoặc tôi không hiểu câu hỏi của bạn đúng cách. Có lẽ bạn có thể giải thích thêm (mẫu mã hoàn chỉnh hơn).

+0

Có và không. Tôi muốn bỏ con trỏ trả về một đối tượng. Tôi sẽ thêm nhiều chi tiết hơn cho câu hỏi của mình. – slaphappy

+0

Tôi đã không nhận thấy rằng phương pháp này cũng hoạt động với các đối tượng. Đây là những gì tôi đang tìm kiếm. Cảm ơn sự giúp đỡ của bạn ! – slaphappy

+0

Tôi chưa bao giờ đến đó nhưng để biết nếu có thể bạn cần đưa ra một mô tả chính xác về những gì thực sự được trả lại. Chính xác thì con trỏ trỏ tới đâu. Hãy xem, nếu bạn đang tương tác với mã không được quản lý, bạn sẽ không thể truyền sang đối tượng được quản lý. Không đời nào biết được chuyện gì xảy ra. – Jeroen

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