2010-07-13 6 views
12

простой вопрос, я импортирую функцию DLL, а параметр - int *. Когда я пытаюсь ввести метод (0), я получаю сообщение об ошибке: «int и int * не могут преобразовать».DotNet - Что такое int *?

В чем смысл?

ответ

15

Это классическое обозначение C для pointer to an int. Всякий раз, когда за типом следует *, он обозначает этот тип как pointer для этого типа. В C#, в отличие от C, вы должны явно определять функции как unsafe для использования указателей, в дополнение к включению кода unsafe в свойствах вашего проекта. Тип указателя также не может быть взаимозаменяемым с конкретным типом, поэтому сначала нужно указать ссылку типа. Чтобы получить указатель на другой тип, такой как int, в C# (или C C++, если на то пошло), вы должны использовать оператор разыменования & (амперсанд) перед переменной, к которой вы хотите получить указатель:

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

«небезопасный» код C#

Ниже приведены некоторые ключевые статьи о небезопасном коде, а также использование указателей в C#.

+0

Чтобы добавить здесь, '&' - это получить указатель (адрес) 'int i' ... – Nate

+0

@Nate: Хорошо, я добавлю лучшее объяснение оператора разыменования. – jrista

+0

Одинаковый комментарий здесь: он не имеет ничего общего с небезопасным кодом. Аргумент просто передается по ссылке. Ключевое слово ref в C#. Это также указатель на C#, к тому моменту, когда компилятор JIT с ним работает. –

6

Это pointer to an int. Как правило, лучше всего избегать управляемого кода. Возможно, вы захотите опубликовать объявление импортированного метода. IntPtr обычно достаточно для такого рода взаимодействия.

+1

Это просто аргумент, который передается по ссылке. Это хорошая поддержка маршаллером P/Invoke, использование IntPtr является ошибкой. –

+2

Зависит от того, что он делает. Если это массив, 'int []' - это то, что вы хотите. Если это дескриптор, 'IntPtr' обычно лучше, особенно если вы планируете передавать 0. Если вам нужна фактическая ссылка на int,' ref int' или 'out int' может работать лучше. – Blindy

+1

Не видя объявления метода, я не смог бы догадаться так или иначе (ref vs array vs pointer). @ Блинди прав на деньги. Зависит от вызываемого метода. Например, LPARAM SendMessage обычно сортируется как IntPtr, и этот парень обычно содержит указатель памяти (который может быть выражен как int *) – dkackman

2

Это зависит от используемого вами языка. В C# вы должны объявить аргумент с ключевым словом «ref». В VB.NET вы должны использовать ключевое слово ByRef. И вам нужно вызвать его, передав переменную, а не константу. Что-то вроде этого:

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

Является ли ref практически таким же, как и используется в принятом ответе? –

+0

Под капотом после того, как дрожание сделано с ним, да. –

+0

Если авторы DLL, которые он использовал, определили подписи C# 'Method (int * p)', то он не может вызвать метод с синтаксисом 'Method (ref retval);' вы предлагаете, правильно? Авторы DLL _could_ вместо этого выбрали подпись 'Method (ref int p)', но по какой-то причине они этого не сделали. C# не предлагает «арифметику» для переменных типа «ref int», таких как приращение к «следующему» адресу, как это делается с указателями 'int * p' (например, C#' p ++ 'и другие,« небезопасные ») , –

Смежные вопросы