Intptr c что это
Let’s do some .NET
Профиль
Группа: Модератор
Сообщений: 2828
Регистрация: 19.12.2005
Где: Санкт-Петербург
Репутация: 8
Всего: 67
musson
| Цитата |
| The IntPtr type is designed to be an integer whose size is platform-specific. That is, an instance of this type is expected to be 32-bits on 32-bit hardware and operating systems, and 64-bits on 64-bit hardware and operating systems. |
СУВ,
Partizan.
| Дата 1.12.2008, 19:31 (ссылка) | (нет голосов) Загрузка . |
Профиль
Группа: Участник
Сообщений: 24
Регистрация: 28.9.2008
Репутация: нет
Всего: нет
Partizan,
т.е. IntPtr это указатель или дескриптор, что такое указатель понятно, а что такое дескриптор?
Это сообщение отредактировал(а) musson — 1.12.2008, 19:35
| Дата 1.12.2008, 19:37 (ссылка) | (нет голосов) Загрузка . |
Let’s do some .NET
Профиль
Группа: Модератор
Сообщений: 2828
Регистрация: 19.12.2005
Где: Санкт-Петербург
Репутация: 8
Всего: 67
musson, ну а чего не понятного? Как правило этот тип представляет собой int* при всякого рода interop сценариях
Int Ptr. Size Свойство
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Получает размер этого экземпляра.
public: static property int Size < int get(); >;
public static int Size
static member Size : int
Public Shared ReadOnly Property Size As Integer
Значение свойства
Размер целого числа со знаком в выполняемом процессе, измеряемый в байтах. Значение этого свойства равно 4 в 32-разрядном процессе и 8 в 64-разрядном процессе. Можно указать тип процесса, задав параметр /platform при компилировании кода с помощью компиляторов C# и Visual Basic.
Int Ptr Структура
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Представляет целое число со знаком, где битовая ширина совпадает с указателем.
public value class IntPtr
public value class IntPtr : IComparable, IComparable, IEquatable, IFormattable, System::Runtime::Serialization::ISerializable
public value class IntPtr : IComparable, IComparable, IEquatable, ISpanFormattable, System::Runtime::Serialization::ISerializable
public value class IntPtr : IComparable, IEquatable, IParsable, ISpanParsable, System::Numerics::IAdditionOperators, System::Numerics::IAdditiveIdentity, System::Numerics::IBinaryInteger, System::Numerics::IBinaryNumber, System::Numerics::IBitwiseOperators, System::Numerics::IComparisonOperators, System::Numerics::IDecrementOperators, System::Numerics::IDivisionOperators, System::Numerics::IEqualityOperators, System::Numerics::IIncrementOperators, System::Numerics::IMinMaxValue, System::Numerics::IModulusOperators, System::Numerics::IMultiplicativeIdentity, System::Numerics::IMultiplyOperators, System::Numerics::INumber, System::Numerics::INumberBase, System::Numerics::IShiftOperators, System::Numerics::ISignedNumber, System::Numerics::ISubtractionOperators, System::Numerics::IUnaryNegationOperators, System::Numerics::IUnaryPlusOperators, System::Runtime::Serialization::ISerializable
public value class IntPtr : IComparable, IEquatable, IParsable, ISpanParsable, IUtf8SpanParsable, System::Numerics::IAdditionOperators, System::Numerics::IAdditiveIdentity, System::Numerics::IBinaryInteger, System::Numerics::IBinaryNumber, System::Numerics::IBitwiseOperators, System::Numerics::IComparisonOperators, System::Numerics::IDecrementOperators, System::Numerics::IDivisionOperators, System::Numerics::IEqualityOperators, System::Numerics::IIncrementOperators, System::Numerics::IMinMaxValue, System::Numerics::IModulusOperators, System::Numerics::IMultiplicativeIdentity, System::Numerics::IMultiplyOperators, System::Numerics::INumber, System::Numerics::INumberBase, System::Numerics::IShiftOperators, System::Numerics::ISignedNumber, System::Numerics::ISubtractionOperators, System::Numerics::IUnaryNegationOperators, System::Numerics::IUnaryPlusOperators, System::Runtime::Serialization::ISerializable
public value class IntPtr : IEquatable, System::Runtime::Serialization::ISerializable
public value class IntPtr : System::Runtime::Serialization::ISerializable
public struct IntPtr
public readonly struct IntPtr : IComparable, IComparable, IEquatable, IFormattable, System.Runtime.Serialization.ISerializable
public readonly struct IntPtr : IComparable, IComparable, IEquatable, ISpanFormattable, System.Runtime.Serialization.ISerializable
public readonly struct IntPtr : IComparable, IEquatable, IParsable, ISpanParsable, System.Numerics.IAdditionOperators, System.Numerics.IAdditiveIdentity, System.Numerics.IBinaryInteger, System.Numerics.IBinaryNumber, System.Numerics.IBitwiseOperators, System.Numerics.IComparisonOperators, System.Numerics.IDecrementOperators, System.Numerics.IDivisionOperators, System.Numerics.IEqualityOperators, System.Numerics.IIncrementOperators, System.Numerics.IMinMaxValue, System.Numerics.IModulusOperators, System.Numerics.IMultiplicativeIdentity, System.Numerics.IMultiplyOperators, System.Numerics.INumber, System.Numerics.INumberBase, System.Numerics.IShiftOperators, System.Numerics.ISignedNumber, System.Numerics.ISubtractionOperators, System.Numerics.IUnaryNegationOperators, System.Numerics.IUnaryPlusOperators, System.Runtime.Serialization.ISerializable
public readonly struct IntPtr : IComparable, IEquatable, IParsable, ISpanParsable, IUtf8SpanParsable, System.Numerics.IAdditionOperators, System.Numerics.IAdditiveIdentity, System.Numerics.IBinaryInteger, System.Numerics.IBinaryNumber, System.Numerics.IBitwiseOperators, System.Numerics.IComparisonOperators, System.Numerics.IDecrementOperators, System.Numerics.IDivisionOperators, System.Numerics.IEqualityOperators, System.Numerics.IIncrementOperators, System.Numerics.IMinMaxValue, System.Numerics.IModulusOperators, System.Numerics.IMultiplicativeIdentity, System.Numerics.IMultiplyOperators, System.Numerics.INumber, System.Numerics.INumberBase, System.Numerics.IShiftOperators, System.Numerics.ISignedNumber, System.Numerics.ISubtractionOperators, System.Numerics.IUnaryNegationOperators, System.Numerics.IUnaryPlusOperators, System.Runtime.Serialization.ISerializable
public struct IntPtr : IEquatable, System.Runtime.Serialization.ISerializable
public readonly struct IntPtr : IEquatable, System.Runtime.Serialization.ISerializable
[System.Serializable] public struct IntPtr : System.Runtime.Serialization.ISerializable
[System.Serializable] [System.Runtime.InteropServices.ComVisible(true)] public struct IntPtr : System.Runtime.Serialization.ISerializable
public struct IntPtr : System.Runtime.Serialization.ISerializable
type nativeint = struct
type nativeint = struct interface IFormattable interface ISerializable
type nativeint = struct interface ISpanFormattable interface IFormattable interface ISerializable
type nativeint = struct interface IFormattable interface IParsable interface ISpanFormattable interface ISpanParsable interface IAdditionOperators interface IAdditiveIdentity interface IBinaryInteger interface IBinaryNumber interface IBitwiseOperators interface IComparisonOperators interface IEqualityOperators interface IDecrementOperators interface IDivisionOperators interface IIncrementOperators interface IModulusOperators interface IMultiplicativeIdentity interface IMultiplyOperators interface INumber interface INumberBase interface ISubtractionOperators interface IUnaryNegationOperators interface IUnaryPlusOperators interface IShiftOperators interface IMinMaxValue interface ISignedNumber interface ISerializable
type nativeint = struct interface IFormattable interface IParsable interface ISpanFormattable interface ISpanParsable interface IAdditionOperators interface IAdditiveIdentity interface IBinaryInteger interface IBinaryNumber interface IBitwiseOperators interface IComparisonOperators interface IEqualityOperators interface IDecrementOperators interface IDivisionOperators interface IIncrementOperators interface IModulusOperators interface IMultiplicativeIdentity interface IMultiplyOperators interface INumber interface INumberBase interface ISubtractionOperators interface IUnaryNegationOperators interface IUnaryPlusOperators interface IUtf8SpanFormattable interface IUtf8SpanParsable interface IShiftOperators interface IMinMaxValue interface ISignedNumber interface ISerializable
type nativeint = struct interface ISerializable
[] type nativeint = struct interface ISerializable
[] [] type nativeint = struct interface ISerializable
Public Structure IntPtr
Public Structure IntPtr Implements IComparable, IComparable(Of IntPtr), IEquatable(Of IntPtr), IFormattable, ISerializable
Public Structure IntPtr Implements IComparable, IComparable(Of IntPtr), IEquatable(Of IntPtr), ISerializable, ISpanFormattable
Public Structure IntPtr Implements IAdditionOperators(Of IntPtr, IntPtr, IntPtr), IAdditiveIdentity(Of IntPtr, IntPtr), IBinaryInteger(Of IntPtr), IBinaryNumber(Of IntPtr), IBitwiseOperators(Of IntPtr, IntPtr, IntPtr), IComparable(Of IntPtr), IComparisonOperators(Of IntPtr, IntPtr, Boolean), IDecrementOperators(Of IntPtr), IDivisionOperators(Of IntPtr, IntPtr, IntPtr), IEqualityOperators(Of IntPtr, IntPtr, Boolean), IEquatable(Of IntPtr), IIncrementOperators(Of IntPtr), IMinMaxValue(Of IntPtr), IModulusOperators(Of IntPtr, IntPtr, IntPtr), IMultiplicativeIdentity(Of IntPtr, IntPtr), IMultiplyOperators(Of IntPtr, IntPtr, IntPtr), INumber(Of IntPtr), INumberBase(Of IntPtr), IParsable(Of IntPtr), ISerializable, IShiftOperators(Of IntPtr, Integer, IntPtr), ISignedNumber(Of IntPtr), ISpanParsable(Of IntPtr), ISubtractionOperators(Of IntPtr, IntPtr, IntPtr), IUnaryNegationOperators(Of IntPtr, IntPtr), IUnaryPlusOperators(Of IntPtr, IntPtr)
Public Structure IntPtr Implements IAdditionOperators(Of IntPtr, IntPtr, IntPtr), IAdditiveIdentity(Of IntPtr, IntPtr), IBinaryInteger(Of IntPtr), IBinaryNumber(Of IntPtr), IBitwiseOperators(Of IntPtr, IntPtr, IntPtr), IComparable(Of IntPtr), IComparisonOperators(Of IntPtr, IntPtr, Boolean), IDecrementOperators(Of IntPtr), IDivisionOperators(Of IntPtr, IntPtr, IntPtr), IEqualityOperators(Of IntPtr, IntPtr, Boolean), IEquatable(Of IntPtr), IIncrementOperators(Of IntPtr), IMinMaxValue(Of IntPtr), IModulusOperators(Of IntPtr, IntPtr, IntPtr), IMultiplicativeIdentity(Of IntPtr, IntPtr), IMultiplyOperators(Of IntPtr, IntPtr, IntPtr), INumber(Of IntPtr), INumberBase(Of IntPtr), IParsable(Of IntPtr), ISerializable, IShiftOperators(Of IntPtr, Integer, IntPtr), ISignedNumber(Of IntPtr), ISpanParsable(Of IntPtr), ISubtractionOperators(Of IntPtr, IntPtr, IntPtr), IUnaryNegationOperators(Of IntPtr, IntPtr), IUnaryPlusOperators(Of IntPtr, IntPtr), IUtf8SpanParsable(Of IntPtr)
Public Structure IntPtr Implements IEquatable(Of IntPtr), ISerializable
Public Structure IntPtr Implements ISerializable
Наследование
Реализации
Примеры
В следующем примере управляемые указатели используются для изменения символов в массиве. После инициализации String объекта и его длины он выполняет следующие действия:
- Вызывает метод для копирования Marshal.StringToHGlobalAnsi строки Юникода в неуправляемую память в виде однобайтового символа ANSI. Метод возвращает IntPtr объект , указывающий на начало неуправляемой строки. В примере Visual Basic этот указатель используется напрямую; В примерах C++, F# и C# он приводится к указателю на байт.
- Вызывает метод для Marshal.AllocHGlobal выделения того же количества байтов, что и неуправляемая строка. Метод возвращает IntPtr объект , указывающий на начало неуправляемого блока памяти. В примере Visual Basic этот указатель используется напрямую; В примерах C++, F# и C# он приводится к указателю на байт.
- В примере Visual Basic определяется переменная с именем offset , равная длине строки ANSI. Он используется для определения смещения в неуправляемой памяти, в которую копируется следующий символ в строке ANSI. Поскольку его начальное значение — это длина строки, операция копирования копирует символ от начала строки до конца блока памяти. В примерах C#, F# и C++ метод вызывается ToPointer , чтобы получить неуправляемый указатель на начальный адрес строки и неуправляемый блок памяти. Они добавляют один указатель меньше длины строки в начальный адрес строки ANSI. Так как указатель неуправляемой строки теперь указывает на конец строки, операция копирования скопирует символ из конца строки в начало блока памяти.
- Использует цикл для копирования каждого символа из строки в неуправляемый блок памяти. В примере Visual Basic вызывается Marshal.ReadByte(IntPtr, Int32) метод для считывания байта (или однобайтового символа) с указанным смещением от управляемого указателя к строке ANSI. Смещение увеличивается с каждой итерацией цикла. Затем он вызывает Marshal.WriteByte(IntPtr, Int32, Byte) метод для записи байта в адрес памяти, определенный начальным адресом неуправляемого блока памяти плюс offset . Затем он уменьшает . offset В примерах C#, F# и C++ выполняется операция копирования, затем уменьшается указатель на адрес следующего расположения в неуправляемой строке ANSI и увеличивается указатель на следующий адрес в неуправляемом блоке.
- Все примеры вызывают Marshal.PtrToStringAnsi для преобразования неуправляемого блока памяти, содержащего скопированную строку ANSI, в управляемый объект Юникода String .
- После отображения исходных и обратных строк все примеры вызывают FreeHGlobal метод , чтобы освободить память, выделенную для неуправляемой строки ANSI и неуправляемого блока памяти.
using namespace System; using namespace System::Runtime::InteropServices; class NotTooSafeStringReverse < public: static void Main() < String^ stringA = "I seem to be turned around!"; int copylen = stringA->Length; // Allocate HGlobal memory for source and destination strings IntPtr sptr = Marshal::StringToHGlobalAnsi(stringA); IntPtr dptr = Marshal::AllocHGlobal(copylen + 1); char *src = (char *)sptr.ToPointer(); char *dst = (char *)dptr.ToPointer(); if (copylen > 0) < // set the source pointer to the end of the string // to do a reverse copy. src += copylen - 1; while (copylen-- >0) < *dst++ = *src--; >*dst = 0; > String^ stringB = Marshal::PtrToStringAnsi(dptr); Console::WriteLine("Original:\n\n", stringA); Console::WriteLine("Reversed:\n", stringB); // Free HGlobal memory Marshal::FreeHGlobal(dptr); Marshal::FreeHGlobal(sptr); > >; int main() < NotTooSafeStringReverse::Main(); >// The progam has the following output: // // Original: // I seem to be turned around! // // Reversed: // !dnuora denrut eb ot mees I
using System; using System.Runtime.InteropServices; class NotTooSafeStringReverse < static public void Main() < string stringA = "I seem to be turned around!"; int copylen = stringA.Length; // Allocate HGlobal memory for source and destination strings IntPtr sptr = Marshal.StringToHGlobalAnsi(stringA); IntPtr dptr = Marshal.AllocHGlobal(copylen + 1); // The unsafe section where byte pointers are used. unsafe < byte *src = (byte *)sptr.ToPointer(); byte *dst = (byte *)dptr.ToPointer(); if (copylen >0) < // set the source pointer to the end of the string // to do a reverse copy. src += copylen - 1; while (copylen-- >0) < *dst++ = *src--; >*dst = 0; > > string stringB = Marshal.PtrToStringAnsi(dptr); Console.WriteLine("Original:\n\n", stringA); Console.WriteLine("Reversed:\n", stringB); // Free HGlobal memory Marshal.FreeHGlobal(dptr); Marshal.FreeHGlobal(sptr); > > // The progam has the following output: // // Original: // I seem to be turned around! // // Reversed: // !dnuora denrut eb ot mees I
#nowarn "9" open System.Runtime.InteropServices open FSharp.NativeInterop [] let main _ = let stringA = "I seem to be turned around!" let mutable copylen = stringA.Length // Allocate HGlobal memory for source and destination strings let sptr = Marshal.StringToHGlobalAnsi stringA let dptr = Marshal.AllocHGlobal(copylen + 1) let mutable src: byte nativeptr = sptr.ToPointer() |> NativePtr.ofVoidPtr let mutable dst: byte nativeptr = dptr.ToPointer() |> NativePtr.ofVoidPtr if copylen > 0 then // set the source pointer to the end of the string // to do a reverse copy. src NativePtr.ofNativeInt while copylen > 0 do copylen NativePtr.write dst dst NativePtr.ofNativeInt src NativePtr.ofNativeInt NativePtr.write dst 0uy let stringB = Marshal.PtrToStringAnsi dptr printfn $"Original:\n\n" printfn $"Reversed:\n" // Free HGlobal memory Marshal.FreeHGlobal dptr Marshal.FreeHGlobal sptr 0 // The progam has the following output: // // Original: // I seem to be turned around! // // Reversed: // !dnuora denrut eb ot mees I
Imports System.Runtime.InteropServices Public Module Example Public Sub Main() Dim stringA As String = "I seem to be turned around!" Dim copylen As Integer = stringA.Length ' Allocate HGlobal memory for source and destination strings Dim sptr As IntPtr = Marshal.StringToHGlobalAnsi(stringA) Dim dptr As IntPtr = Marshal.AllocHGlobal(copylen) Dim offset As Integer = copylen - 1 For ctr As Integer = 0 To copylen - 1 Dim b As Byte = Marshal.ReadByte(sptr, ctr) Marshal.WriteByte(dptr, offset, b) offset -= 1 Next Dim stringB As String = Marshal.PtrToStringAnsi(dptr) Console.WriteLine("Original:", stringA, vbCrLf) Console.WriteLine("Reversed:", stringB, vbCrLf) ' Free HGlobal memory Marshal.FreeHGlobal(dptr) Marshal.FreeHGlobal(sptr) End Sub End Module ' The example displays the following output: ' Original: ' I seem to be turned around! ' ' Reversed: ' !dnuora denrut eb ot mees I
Комментарии
Тип IntPtr предназначен для целого числа, размер которого совпадает с размером указателя. То есть экземпляр этого типа должен быть 32-разрядным в 32-разрядном процессе и 64 битом в 64-разрядном процессе.
Тип IntPtr может использоваться языками, поддерживающими указатели, и в качестве общего средства ссылки на данные между языками, которые поддерживают и не поддерживают указатели.
IntPtr Объекты также можно использовать для хранения дескрипторов. Например, экземпляры IntPtr широко используются в System.IO.FileStream классе для хранения дескрипторов файлов.
Использование IntPtr в качестве указателя или дескриптора подвержено ошибкам и небезопасно. Это просто целочисленный тип, который можно использовать в качестве формата обмена для указателей и дескрипторов из-за одного размера. Помимо конкретных требований к обмену, например для передачи данных на язык, который не поддерживает указатели, для представления указателей следует использовать правильно типизированный указатель, а SafeHandle также для представления дескрипторов.
Этот тип реализует ISerializable. В .NET 5 и более поздних версиях этот тип также реализует IFormattable интерфейсы . В .NET 7 и более поздних версиях этот тип также реализует интерфейсы IBinaryInteger , IMinMaxValue и ISignedNumber .
В C# начиная с версии 9.0 можно использовать встроенный nint тип для определения целых чисел собственного размера. Этот тип представлен внутренним типом IntPtr и обеспечивает операции и преобразования, подходящие для целочисленных типов. Дополнительные сведения см. в разделе Типы nint и nuint.
В C# начиная с версии 11 и при использовании среды выполнения .NET 7 или более поздней версии является псевдонимом для IntPtr так же, nint как int и псевдонимом для Int32.
Конструкторы
Инициализирует новый экземпляр , IntPtr используя указанное 32-разрядное целое число со знаком.
Инициализирует новый экземпляр , IntPtr используя указанное 64-разрядное целое число со знаком.
Инициализирует новый экземпляр структуры IntPtr с использованием заданного указателя на незаданный тип.
Поля
Доступное только для чтения поле, представляющее целое число со знаком, инициализированное нулевым значением.
Свойства
Возвращает максимально возможное значение .IntPtr
Возвращает наименьшее возможное значение .IntPtr
Получает размер этого экземпляра.
Методы
Вычисляет абсолютное значение.
Добавляет смещение в целое число со знаком.
Зажимает значение до минимального и максимального значений включительно.
Сравнивает текущий экземпляр с другим объектом того же типа и возвращает целое число, которое показывает, расположен ли текущий экземпляр перед, после или на той же позиции в порядке сортировки, что и другой объект.
Сравнивает текущий экземпляр с другим объектом того же типа и возвращает целое число, которое показывает, расположен ли текущий экземпляр перед, после или на той же позиции в порядке сортировки, что и другой объект.
Копирует знак значения в знак другого значения.
Создает экземпляр текущего типа из значения, вызывая исключение переполнения для всех значений, которые выходят за пределы диапазона, представляющего текущий тип.
Создает экземпляр текущего типа из значения, насыщая все значения, которые выходят за пределы представляемого диапазона текущего типа.
Создает экземпляр текущего типа из значения, усекая все значения, которые выходят за пределы представляемого диапазона текущего типа.
Вычисляет частное и оставшееся число двух значений.
Указывает, равен ли текущий объект другому объекту того же типа.
Возвращает значение, показывающее, равен ли данный экземпляр заданному объекту.
Возвращает хэш-код данного экземпляра.
Определяет, представляет ли значение четное целое число.
Определяет, является ли значение отрицательным.
Определяет, представляет ли значение нечетное целое число.
Определяет, является ли значение положительным.
Определяет, является ли значение степенью 2.
Вычисляет число начальных нулей в значении.
Вычисляет значение log2.
Сравнивает два значения, чтобы вычислить большее значение.
Сравнивает два значения, чтобы вычислить большее значение.
Сравнивает два значения для вычисления меньшего значения.
Сравнивает два значения для вычисления меньшего значения.
Анализирует диапазон символов UTF-8 в значение.
Анализирует диапазон символов UTF-8 в значение.
Анализирует диапазон символов в значение.
Преобразует доступное только для чтения представление символов числа в указанном стиле и формате, зависят от языка и региональных параметров, в эквивалентное ей собственное целое число со знаком.
Преобразует строковое представление числа в эквивалентное ему собственное целое число со знаком.
Преобразует строковое представление числа в формате, зависящем от языка и региональных параметров, в эквивалентное ему собственное целое число со знаком.
Преобразует строковое представление числа в указанном стиле в эквивалентное ему собственное целое число со знаком.
Преобразует строковое представление числа в указанном стиле и формате, зависящем от языка и региональных параметров, в эквивалентное ему собственное целое число со знаком.
Вычисляет количество битов, заданных в значении .
Поворачивает значение влево на заданную величину.
Поворачивает значение вправо на заданную величину.
Вычисляет знак значения.
Вычитает смещение из целого числа со знаком.
Преобразует значение этого экземпляра в формат 32-разрядного целого числа со знаком.
Преобразует значение этого экземпляра в формат 64-разрядного целого числа со знаком.
Преобразует значение этого экземпляра в указатель незаданного типа.
Преобразует числовое значение текущего объекта IntPtr в эквивалентное ему строковое представление.
Преобразует числовое значение данного экземпляра в эквивалентное ему строковое представление с использованием указанного формата и сведений об особенностях форматирования для данного языка и региональных параметров.
Преобразует числовое значение текущего объекта IntPtr в эквивалентное ему строковое представление.
Форматирует значение текущего экземпляра, используя указанный формат.
Вычисляет число конечных нулей в значении.
Пытается отформатировать значение текущего экземпляра как UTF-8 в предоставленный диапазон байтов.
Пытается отформатировать значение текущего экземпляра в указанный диапазон символов.
Пытается проанализировать диапазон символов UTF-8 в значение.
Пытается преобразовать диапазон символов UTF-8, содержащий строковое представление числа, в эквивалентное ей целое число со знаком.
Пытается проанализировать диапазон символов UTF-8 в значение.
Пытается проанализировать строку в значение.
Преобразует доступное только для чтения представление символов числа в эквивалентное ей собственное целое число со знаком. Возвращает значение, указывающее, успешно ли выполнено преобразование.
Преобразует доступное только для чтения представление символов числа в указанном стиле и формате, зависят от языка и региональных параметров, в эквивалентное ей собственное целое число со знаком. Возвращает значение, указывающее, успешно ли выполнено преобразование.
Пытается проанализировать строку в значение.
Преобразует строковое представление числа в эквивалентное ему собственное целое число со знаком. Возвращает значение, указывающее, успешно ли выполнено преобразование.
Преобразует строковое представление числа в указанном стиле и формате, зависящем от языка и региональных параметров, в эквивалентное ему собственное целое число со знаком. Возвращает значение, указывающее, успешно ли выполнено преобразование.
Операторы
Добавляет смещение в целое число со знаком.
Определяет, равны ли два заданных экземпляра класса IntPtr.
Преобразует 32-разрядное целочисленное значение со знаком в IntPtr.
Преобразует 64-разрядное целочисленное значение со знаком в IntPtr.
Преобразует значение заданной структуры IntPtr в формат 32-разрядного целого числа со знаком.
Преобразует значение заданной структуры IntPtr в формат 64-разрядного целого числа со знаком.
Преобразует значение заданной структуры IntPtr в указатель на незаданный тип.
Этот интерфейс API CLS-несовместим.
Преобразует заданный указатель на незаданный тип в IntPtr.
Этот интерфейс API CLS-несовместим.
Определяет, являются ли два заданных экземпляра класса IntPtr неравными.
Вычитает смещение из целого числа со знаком.
Явные реализации интерфейса
Добавляет два значения вместе для вычисления их суммы.
Добавляет два значения вместе для вычисления их суммы.
Возвращает аддитивное удостоверение текущего типа.
Возвращает количество байтов, которые будут записаны в составе TryWriteLittleEndian(Span, Int32).
Возвращает длину (в битах) представления текущего значения в дополнение к кратчайшему двум.
Представляет целое число со знаком, где битовая ширина совпадает с указателем.
Представляет целое число со знаком, где битовая ширина совпадает с указателем.
Пытается записать текущее значение в формате big-endian в заданный диапазон.
Пытается записать текущее значение в малобайтовом формате в заданный диапазон.
Возвращает экземпляр двоичного типа, в котором заданы все биты.
Вычисляет побитовое и двух значений.
Вычисляет побитовое значение или из двух значений.
Вычисляет исключающее значение или из двух значений.
Вычисляет представление с дополнением к единицам заданного значения.
Сравнивает два значения, чтобы определить, какое значение больше.
Сравнивает два значения, чтобы определить, какое значение больше или равно.
Сравнивает два значения, чтобы определить, какое значение меньше.
Сравнивает два значения, чтобы определить, какое значение меньше или равно.
Делит одно значение на другое для вычисления их частного значения.
Возвращает значение, указывающее, равен ли этот экземпляр другому целому значению со знаком.
Возвращает максимальное значение текущего типа.
Возвращает минимальное значение текущего типа.
Делит два значения для вычисления их модуля или остатка.
Возвращает мультипликативное удостоверение текущего типа.
Умножает два значения вместе для вычисления их продукта.
Умножает два значения вместе для вычисления их продукта.
Сравнивает два значения для вычисления, которое больше, и возвращает другое значение, если входные данные имеют значение NaN .
Сравнивает два значения для вычисления меньшего значения и возвращает другое значение, если входные данные имеют значение NaN .
Определяет, находится ли значение в своем каноническом представлении.
Определяет, представляет ли значение комплексное число.
Определяет, является ли значение конечным.
Определяет, представляет ли значение чистое мнимое число.
Определяет, является ли значение бесконечным.
Определяет, представляет ли значение целое число.
Определяет, является ли значение NaN.
Определяет, является ли значение отрицательным бесконечностью.
Определяет, является ли значение нормальным.
Определяет, является ли значение положительным бесконечностью.
Определяет, представляет ли значение реальное число.
Определяет, является ли значение субнормальным.
Определяет, равно ли значение нулю.
Сравнивает два значения для вычисления, которое имеет большую величину, и возвращает другое значение, если входные данные имеют значение NaN .
Сравнивает два значения для вычисления, которое имеет меньшую величину, и возвращает другое значение, если входные данные имеют значение NaN .
Возвращает значение 1 для типа.
Возвращает основание для типа.
Представляет целое число со знаком, где битовая ширина совпадает с указателем.
Представляет целое число со знаком, где битовая ширина совпадает с указателем.
Представляет целое число со знаком, где битовая ширина совпадает с указателем.
Пытается преобразовать экземпляр текущего типа в другой тип, вызывая исключение переполнения для всех значений, которые выходят за пределы диапазона, представляющего текущий тип.
Пытается преобразовать экземпляр текущего типа в другой тип, насыщая все значения, которые выходят за пределы представляемого диапазона текущего типа.
Пытается преобразовать экземпляр текущего типа в другой тип, усекая все значения, которые выходят за пределы представляемого диапазона текущего типа.
Возвращает значение 0 для типа.
Заполняет объект SerializationInfo данными, необходимыми для сериализации текущего объекта IntPtr.
Сдвигает значение влево на заданную величину.
Сдвигает значение вправо на заданную величину.
Сдвигает значение вправо на заданную величину.
Возвращает значение -1 для типа.
Вычитает два значения, чтобы вычислить их разницу.
Вычитает два значения, чтобы вычислить их разницу.
Вычисляет проверенное унарное отрицание значения.
Вычисляет унарное отрицание значения.
Вычисляет унарный плюс значения.
Расширения языка C++/CLI

— это набор расширений языка C++, позволяющий создавать гибридные управляемые и низкоуровневые библиотеки DLL. С применением расширений C++/CLI вы сможете определять управляемые и неуправляемые классы и функции в пределах одного файла .cpp, использовать управляемые и низкоуровневые типы C и C++, как в обычном программном коде на C++, то есть простым подключением заголовочного файла и связыванием с библиотекой. Эти широчайшие возможности можно использовать для создания управляемых типов-оберток, пригодных для использования в любом языке .NET, а так же низкоуровневые классы-обертки и функции (доступные через файлы .dll, .lib и .h), пригодные для использования в программном коде на C/C++.
При использовании расширения C++/CLI маршалинг выполняется вручную, благодаря чему разработчик имеет более полный контроль и более полное представление о накладных расходах. Расширение C++/CLI с успехом можно использовать там, где механизм P/Invoke оказывается бесполезен, например, для маршалинга структур переменной длины. Еще одно преимущество расширения C++/CLI состоит в том, что оно позволяет имитировать интерфейс объединения запросов, даже если у вас нет доступа к исходным текстам вызывающего кода, многократно вызывая низкоуровневые методы без необходимости каждый раз пересекать границу между управляемым и неуправляемым кодом.
В коде, представленном ниже, мы реализовали неуправляемый класс NativeEmployee и управляемый класс Employee, служащий оберткой для первого. Управляемый код будет обращаться только к управляемому классу.
#include #include #include #include using namespace System; using namespace System::Runtime::InteropServices; class NativeEmployee < public: NativeEmployee(const wchar_t *employeeName, int age) : _employeeName(employeeName), _employeeAge(age) < >void DoWork(const wchar_t **tasks, int numTasks) < for (int i = 0; i < numTasks; i++) < wprintf(L"Пользователь %s работает в задаче %s\n", _employeeName.c_str(), tasks[i]); >> int GetAge() const < return _employeeAge; >const wchar_t *GetName() const < return _employeeName.c_str(); >private: std::wstring _employeeName; int _employeeAge; >; #pragma managed namespace EmployeeLib < public ref class Employee < < public: Employee(String ^employeeName, int age) < // Вариант 1: // IntPtr pEmployeeName = Marshal::StringToHGlobalUni(employeeName); // m_pEmployee = new NativeEmployee( // reinterpret_cast(pEmployeeName.ToPointer()), age); // Marshal::FreeHGlobal(pEmployeeName); // Вариант 2 (прямой указатель на закрепленную // управляемую строку, самый быстрый): pin_ptr ppEmployeeName = PtrToStringChars(employeeName); _employee = new NativeEmployee(ppEmployeeName, age); > ~Employee() < delete _employee; _employee = nullptr; >int GetAge() < return _employee->GetAge(); > String ^GetName() < // Вариант 1: // return Marshal::PtrToStringUni( // (IntPtr)(void *) _employee->GetName()); // Вариант 2: return msclr::interop::marshal_as(_employee->GetName()); // Вариант 3 (самый быстрый): return gcnew String(_employee->GetName()); > void DoWork(array^ tasks) < // marshal_context - это управляемый класс, размещаемый // (в динамической памяти сборщика мусора) с использованием // семантики, напоминающей стек. Его деструктор IDisposable::Dispose() // будет вызван после выхода из области видимости этой функции msclr::interop::marshal_context ctx; const wchar_t **pTasks = new const wchar_t*[tasks->Length]; for (int i = 0; i < tasks->Length; i++) < String ^t = tasks[i]; pTasks[i] = ctx.marshal_as(t); > m_pEmployee->DoWork(pTasks, tasks->Length); // деструктор контекста освободит неуправляемую // память, выделенную методом marshal_as delete[] pTasks; > private: NativeEmployee *_employee; >; >
Взглянув на код, можно увидеть, что конструктор Employee демонстрирует два способа преобразования управляемых строк в неуправляемый: первый основан на выделении памяти с помощью GlobalAlloc, которую необходимо будет освободить явно, а второй временно закрепляет управляемую строку в памяти и возвращает прямой указатель. Второй способ выполняется быстрее, но его можно использовать, только когда неуправляемый код принимает строки, завершающиеся нулевым символом, в кодировке UTF-16, и он не записывает ничего в память по указателю. Кроме того, закрепление управляемых объектов на длительное время может привести к фрагментации памяти, поэтому, если перечисленные требования не удовлетворяются, вам придется прибегнуть к копированию строк.
Метод GetName() класса Employee демонстрирует три способа преобразования неуправляемых строк в управляемые: первый основан на использовании класса System.Runtime.InteropServices.Marshal, второй использует функцию marshal_as, объявленную в заголовочном файле msclr/marshal.h, и, наконец, третий использует конструктор класса System.String, являющийся наиболее быстрым.
Метод DoWork() класса Employee принимает управляемый массив (или управляемые строки) и преобразует его в массив указателей типа wchar_t, указывающих на строки; фактически это массив строк в стиле языка C. Преобразование управляемых строк в неуправляемые выполняется с применением метода marshal_as класса объекта marshal_context. В отличие от глобальной функции marshal_as, объект marshal_context используется для преобразований, требующих освобождения занимаемых при этом ресурсов. Обычно для преобразования управляемых данных в неуправляемые метод marshal_as выделяет неуправляемую память, которую следует освободить после выполнения операции. Объект marshal_context содержит связанный список операций освобождения ресурсов, которые выполняются в момент уничтожения объекта.
Подводя итоги можно сказать, что расширение C++/CLI обеспечивает полный контроль над маршалингом и не требует дублирования объявлений функций, что чревато ошибками, особенно когда часто приходится изменять сигнатуры неуправляемых функций.
Вспомогательная библиотека marshal_as
В этом разделе мы остановимся на вспомогательной библиотеке marshal_as, входящей в состав версии Visual C++ 2008 и выше. marshal_as — это библиотека шаблонов, упрощающая реализацию маршалиига управляемых типов в неуправляемые и обратно. Она способна преобразовывать многие неуправляемые строковые типы, такие как char*, wchar_t*, std::string, std::wstring, CStringT, CStringT, BSTR, bstr_t и CComBSTR, в управляемые типы и обратно. Она способна автоматически выполнять преобразование символов Юникода и ANSI, а также выделять и освобождать память.
Библиотека объявлена и реализована в файлах marshal.h (базовые типы), marshal_windows.h (типы Windows), marshal_cppstd.h (типы данных STL) и marshal_atl.h (типы данных ATL).
Имеется возможность расширять библиотеку marshal_as реализацией преобразований пользовательских типов. Это помогает избежать дублирования кода, когда требуется организовать маршалинг одного и того же типа во многих местах в программе, и дает возможность обеспечить единообразие синтаксиса маршалинга разных типов.
В следующем фрагменте демонстрируется пример расширения библиотеки marshal_as поддержкой преобразования управляемого массива строк в эквивалентный неуправляемый массив строк:
namespace msclr < namespace interop < template<>ref class context_node^> : public context_node_base < private: const wchar_t** _tasks; marshal_context _context; public: context_node(const wchar_t**& toObject, array^ fromObject) < // здесь начинается логика преобразования _tasks = NULL; const wchar_t **pTasks = new const wchar_t*[fromObject->Length]; for (int i = 0; i < fromObject->Length; i++) < String ^t = fromObject[i]; pTasks[i] = _context.marshal_as(t); > toObject = _tasks = pTasks; > ~context_node() < this->!context_node(); > protected: !context_node() < // При удалении контекста будет освобождена память, // выделенная для строк (и принадлежащая marshal_context), // поэтому массив - единственная память, // которую требуется освободить if (_tasks != nullptr) < delete[] _tasks; _tasks = nullptr; >> >; > > // Теперь можно переписать метод Employee::DoWork: void DoWork(array^ tasks) < // Вся неуправляемая память освобождается автоматически, // как только marshal_context выйдет из области видимости msclr::interop::marshal_context ctx; _employee->DoWork(ctx.marshal_as(tasks), tasks->Length); >
Код на языке IL и неуправляемый код
Неуправляемый класс по умолчанию будет скомпилирован расширением C++/CLI в код на языке IL, а не в машинный код. Это может ухудшать производительность в сравнении с оптимизированным машинным кодом, потому что компилятор Visual C++ способен оптимизировать код лучше, чем JIT-компилятор.
Чтобы повлиять на процедуру компиляции можно, добавив объявление #pragma unmanaged или #pragma managed перед требуемым разделом кода. Кроме того, в проектах VC++ имеется возможность включать поддержку C++/CLI для отдельных единиц компиляции (файлов .cpp).
Эффективные приемы взаимодействий
Итак, в этой и предыдущих статьях вы познакомились с небезопасным кодом, особенностями реализации различных механизмов взаимодействий, влиянием на производительность каждой из особенностей и узнали, как можно ослабить это влияние. Вашему вниманию были представлены наиболее эффективные приемы увеличения производительности операций взаимодействий и упрощения их реализации (например, с помощью библиотеки marshal_as и генератора сигнатур для P/Invoke). Давайте подытожим все приведенные ранее советы, относительно небезопасного кода.
Ниже перечислены наиболее эффективные приемы реализации взаимодействий:
- проектируя интерфейсы, старайтесь сводить к минимуму количество переходов через границу между управляемым и неуправляемым кодом, например, объединяя задания;
- уменьшайте количество взаимодействий, совмещая несколько вызовов простых функций в одном вызове;
- реализуйте интерфейс IDisposable, если неуправляемые ресурсы сохраняются между вызовами;
- используйте пулы памяти и выделяйте блоки неуправляемой памяти;
- используйте небезопасный код для интерпретации данных (например, в сетевых протоколах);
- явно именуйте вызываемые функции и используйте ExactSpelling=true;
- используйте параметры двоично совместимых типов, где это возможно;
- избегайте преобразования Юникода в ANSI, когда это возможно;
- вручную преобразуйте строки в/из IntPtr;
- используйте расширение C++/CLI, обеспечивающее лучшие управляемость и производительность при взаимодействиях с кодом на C/C++ и COM-объектами;
- указывайте атрибуты [In] и [Out], чтобы избежать ненужного маршалинга;
- избегайте закрепления долгоживущих объектов;
- используйте метод ReleaseComObject при необходимости;
- используйте атрибут SuppressUnmanagedCodeSecurityAttribute в окружениях, заслуживающих доверия;
- используйте утилиту tlbimp.exe с ключом /unsafe в окружениях, заслуживающих доверия;
- избегайте или старайтесь уменьшать количество вызовов через границы подразделений COM;
- при возможности используйте атрибут AspCompat в приложениях ASP.NET, чтобы уменьшить количество вызовов через границы подразделений COM.