2010-07-13 36 views
12

câu hỏi đơn giản, tôi nhập một hàm DLL và tham số là int *. Khi tôi cố gắng nhập Phương thức (0), tôi nhận được thông báo lỗi: "int và int * không thể chuyển đổi".DotNet - Int * là gì?

Ý nghĩa đó là gì?

Trả lời

15

Đó là ký hiệu C cổ điển cho số pointer to an int. Bất cứ khi nào một loại được theo sau bởi một *, nó biểu thị loại đó là pointer cho loại đó. Trong C#, không giống như trong C, bạn phải xác định rõ ràng các hàm như unsafe để sử dụng con trỏ, ngoài việc bật mã unsafe trong thuộc tính dự án của bạn. Một kiểu con trỏ cũng không trực tiếp hoán đổi cho nhau với một kiểu cụ thể, do đó tham chiếu của một kiểu phải được thực hiện trước tiên. Để có một con trỏ tới kiểu khác, chẳng hạn như int, trong C# (hoặc C & C++ cho vấn đề đó), bạn phải sử dụng toán tử dereference & (dấu và) ở phía trước biến mà bạn muốn trỏ tới:

unsafe 
{ 
    int i = 5; 
    int* p = &i; 
    // Invoke with pointer to i 
    Method(p); 
} 

'không an toàn' mã C#

Dưới đây là một số điều quan trọng trên mã không an toàn và sử dụng con trỏ trong C#.

+0

Để thêm vào đây, '&' là lấy con trỏ (địa chỉ) của 'int i' ... – Nate

+0

@Nate: Tốt, tôi sẽ thêm giải thích tốt hơn về toán tử dereference. – jrista

+0

Cùng một bình luận ở đây: nó không có gì để làm với mã không an toàn. Đối số chỉ đơn giản là được chuyển qua tham chiếu. Từ khóa "ref" trong C#. Nó là một con trỏ trong C# cũng như thời gian trình biên dịch JIT được thực hiện với nó. –

6

Đó là pointer to an int. Nói chung tránh được tốt nhất trong mã được quản lý. Bạn có thể muốn đăng khai báo phương thức đã nhập của mình. IntPtr thường đủ cho loại interop này.

+1

Nó chỉ là một đối số được chuyển qua tham chiếu. Nó cũng được hỗ trợ bởi P/Invoke marshaller, sử dụng IntPtr là một sai lầm. –

+2

Phụ thuộc vào những gì nó làm. Nếu nó là một mảng, 'int []' là những gì bạn muốn. Nếu nó là một xử lý, 'IntPtr' thường là tốt nhất, đặc biệt là nếu bạn có kế hoạch đi qua 0. Nếu bạn muốn một tham chiếu thực sự đến một int,' ref int' hoặc 'out int' có thể làm việc tốt hơn. – Blindy

+1

Nếu không nhìn thấy khai báo phương pháp tôi sẽ không thể đoán một cách này hay cách khác (ref vs mảng vs con trỏ). @Blindy là đúng về tiền. Phụ thuộc vào phương pháp được gọi. Ví dụ, hàm LPARAM của SendMessage thường được sắp xếp như một IntPtr và anh ta thường giữ một con trỏ bộ nhớ (có thể được biểu diễn dưới dạng int *) – dkackman

2

Tùy thuộc vào ngôn ngữ bạn sử dụng. Trong C#, bạn nên khai báo đối số bằng từ khóa "ref". Trong VB.NET, bạn nên sử dụng từ khóa ByRef. Và bạn cần phải gọi nó bằng cách truyền một biến, không phải là hằng số. Một cái gì đó như thế này:

int retval = 0; 
Method(ref retval); 
// Do something with retval 
//... 
+0

Có thực tế giống như & được sử dụng trong câu trả lời được chấp nhận không? –

+0

Dưới mui xe sau khi jitter được thực hiện với nó, có. –

+0

Nếu các tác giả của DLL ông đã sử dụng quyết định chữ ký C# 'Method (int * p)', thì anh ta không thể gọi phương thức với cú pháp 'Method (ref retval);' bạn đề xuất, đúng không? Các tác giả của DLL _could_ đã chọn chữ ký 'Method (ref int p)' thay vào đó, nhưng vì lý do nào đó mà chúng không có. C# không cung cấp "số học" trên các biến kiểu 'ref int', chẳng hạn như tăng dần đến địa chỉ" tiếp theo ", cách nó thực hiện với con trỏ' int * p' (như C# 'p ++' và các biến khác "không an toàn") . –

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