#c# #c #arrays #integer
#c# #c #массивы #целое число
Вопрос:
Я конвертирую некоторый код с C на C #, и мне нужно некоторое представление о том, как работать с такими строками:
PDWORD rgb32_data = (PDWORD) malloc(640*480*4);
Насколько я понимаю, PDWORD
тип представляет целое число без знака (32 бита). Какая была бы хорошая стратегия C # для реализации подобной структуры?
РЕДАКТИРОВАТЬ: Я понял, что мне нужно использовать IntPtr для замены PDWORD, но IntPtr будет содержать одно значение, а не множество значений, как в массиве. Есть предложения по C #?
EDIT2: Uint[] s у меня не работают — к сожалению, единственный способ заставить программу скомпилироваться со всеми ее зависимостями — это ввести IntPtr в качестве аргумента, а не IntPtr[] .
Спасибо.
РЕДАКТИРОВАТЬ — я отметил решение, кроме того, мне нужно было сделать следующее:
Поскольку мне нужен был приведение IntPtr, я добавил этот код
IntPtr rgb32_ptr;
GCHandle handle = GCHandle.Alloc(rgb32_data, GCHandleType.Pinned);
try
{
rgb32_ptr = handle.AddrOfPinnedObject();
}
finally
{
if (handle.IsAllocated)
{
handle.Free();
}
}
чтобы получить то же самое значение IntPtr.
Ответ №1:
Согласно MSDN, PDWORD
определяется как:
typedef DWORD* PDWORD;
Итак, это указатель на a DWORD
, который, как также говорит MSDN, является 32-разрядным целым числом без знака — другими словами, a uint
.
Обратите внимание, что ваша строка кода C выделяет память для массива размером 640 * 480 = 307 200 DWORD
секунд.
Вы могли бы перевести это непосредственно как:
uint[] rgb32_data = new uint[640 * 480];
Но код может действительно захотеть использовать его просто как последовательность байтов в памяти, поэтому вместо этого вы можете захотеть использовать массив байтов
byte[] rgb32_data = new byte[640 * 480 * 4];
и используйте методы в классе BitConverter (особенно ToInt32()
метод), если вы считаете, что это ближе к тому, как оригинальная программа обрабатывает данные.
Комментарии:
1. Хороший улов. Я должен был понять, что он хочет выделить массив. Поскольку исходный код делает это
PDWORD
, я подозреваю, что первое — массив целых чисел без знака.2. Да, это то, что я сделал. В дополнение к этому, поскольку мне требовалось приведение IntPtr, я добавил этот код GCHandle handle = GCHandle. Выделить (rgb32Source, GCHandleType. Закреплено); попробуйте { rgb32_data = обрабатывать. Добавить prof pinnedobject(); } наконец { если (обрабатывать. Выделено) { дескриптор. Освободить(); } }
Ответ №2:
Вы можете использовать небезопасные указатели и Marshal.AllocHGlobal()
Program()
{
unsafe
{
IntPtr ptr = Marshal.AllocHGlobal(640 * 480 * 4);
uint* ptr2 = (uint*)ptr.ToPointer();
for (int i = 0; i < 640*480; i )
{
ptr2[i] = 0;
}
Marshal.FreeHGlobal(ptr);
}
}
Ответ №3:
PDWORD — это указатель на 32-разрядное целое число без знака. В C # это было бы ref uint32
. Или IntPtr
если вы используете 32-разрядную среду выполнения.
Это зависит от того, как вы собираетесь его использовать. Если вы передаете его в неуправляемый код, то я бы предложил ref UInt32
. Если вы используете его для выделения памяти (например, возвращаемое значение из функции Windows API, которая выделяет память), тогда вы хотели бы использовать IntPtr
.
Комментарии:
1. Как бы я использовал IntPtr? Я добавил это в свою правку. Разве IntPtr не выдал бы мне просто одно значение? Какой тип ссылки я мог бы использовать?
2. @sparkFinder: Вам просто нужно выделить массив. Ответ Лукаса Джонса, вероятно, то, что вы ищете.
3. Это то, что я сделал изначально — к сожалению, единственный способ заставить программу скомпилироваться со всеми ее зависимостями — это ввести IntPtr в качестве аргумента, а не IntPtr[]
4. @sparkFinder: Я не могу представить, что здесь нужно использовать массив
IntPtr
. Можете ли вы предоставить нам больше контекста?5. Мне сложно это сделать, просто методу, который в конечном итоге принимает rgb32_data в качестве аргумента, нужен IntPtr в качестве аргумента. Как я смогу упаковать свой код, используя его? Я думал использовать IntPtr [] вместо uint [], который также был предложен здесь, но я могу использовать только IntPtr (что и пытался сказать мой предыдущий комментарий). Я новичок в C #, поэтому, возможно, я просто упускаю из виду какую-то ключевую концепцию. Приветствия 🙂
Ответ №4:
PDWORD — это указатель на DWORD. Существует несколько вариантов преобразования кода в C # в зависимости от того, как он будет использоваться.
Для самого DWORD вы можете использовать System.UInt32 в качестве эквивалента. Маршалировать.В качестве замены можно использовать AllocHGlobal, но нам нужно посмотреть, как он будет использоваться. Вы обращаетесь к памяти самостоятельно или, возможно, передаете ее другой неуправляемой функции?