Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.52/21: Рейтинг темы: голосов - 21, средняя оценка - 4.52
2 / 2 / 1
Регистрация: 07.12.2013
Сообщений: 83
.NET 2.x

Marshal.StructureToPtr

06.02.2018, 18:19. Показов 4413. Ответов 17
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Пытаюсь освоить Marshal.StructureToPtr и Marshal.PtrToStructure

Массивом байт я уже могу заполнить структуру:
Кликните здесь для просмотра всего текста

C#
1
2
3
4
5
6
7
8
private static structure FillStructure<structure>(byte[] Buffer)
        {
            structure Ret;
            GCHandle handle = GCHandle.Alloc(Buffer, GCHandleType.Pinned);
            Ret = (structure)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(structure));
            handle.Free();
            return Ret;
        }

а вот наоборот не получается, вылетает без ошибок.
Кликните здесь для просмотра всего текста

C#
1
2
3
4
5
6
7
private static byte[] FillBytes<structure>(structure Buffer)
        {
            byte[] Ret = new byte[Marshal.SizeOf(typeof(structure))];
            var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(structure)));
            Marshal.StructureToPtr(Ret, ptr, true);
            return Ret;
        }
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
06.02.2018, 18:19
Ответы с готовыми решениями:

Что такое класс Marshal
подскажите, для каких целей используется класс Marshal

Мусор при использовании класса Marshal
Здравствуйте, форумчане. Имеется тестовая функция на С++ которая возвращает строку в код на С#. Но есть небольшой баг который я не могу...

Получение указателя через Marshal.GetFunctionPointerForDelegate
Итак, есть код: public static class HookDrive { ///&lt;summary&gt; /// Initialize hook ///&lt;/summary&gt; ...

17
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
06.02.2018, 19:10
Цитата Сообщение от -VIRUS- Посмотреть сообщение
а вот наоборот не получается, вылетает без ошибок.
Первым-то аргументом в StructureToPtr надо структуру передавать (Buffer), а не массив (Ret)
0
2 / 2 / 1
Регистрация: 07.12.2013
Сообщений: 83
06.02.2018, 19:13  [ТС]
да я по ходу ее в обще не вкурил.
вот так криво работает:
но почему то структура 15 байт, а массив 20 получается.
C#
1
2
3
4
5
6
7
8
9
10
11
private static byte[] FillBytes<structure>(structure Buffer)
        {
            byte[] Ret = new byte[Marshal.SizeOf(typeof(structure))];
            var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(structure))); // указатель
            Marshal.StructureToPtr(Buffer, ptr, false); // копируем структуру в память
            for (int i = 0; i < Ret.Length; i++) {
                Ret[i] = Marshal.ReadByte(ptr, i);
            }
 
            return Ret;
        }
0
139 / 139 / 53
Регистрация: 14.06.2016
Сообщений: 467
06.02.2018, 19:14
Цитата Сообщение от -VIRUS- Посмотреть сообщение
но почему то структура 15 байт, а массив 20 получается
выравнивание
0
2 / 2 / 1
Регистрация: 07.12.2013
Сообщений: 83
06.02.2018, 19:15  [ТС]
C#
1
2
3
4
5
6
7
8
9
        private struct _Request
        {
            public UInt16 A01_Function;
            public UInt32 A02_Direction;
            public byte A03_Request;
            public UInt16 A04_Value;
            public UInt16 A05_Index;
            public UInt32 A06_Length;
    }
Добавлено через 21 секунду
а как исправить?
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
06.02.2018, 19:17
Лучший ответ Сообщение было отмечено OwenGlendower как решение

Решение

Цитата Сообщение от -VIRUS- Посмотреть сообщение
а как исправить?
C#
1
2
3
4
5
6
7
8
9
10
[StructLayout(LayoutKind.Sequential, Pack = 1)]
private struct _Request
{
   public UInt16 A01_Function;
   public UInt32 A02_Direction;
   public byte A03_Request;
   public UInt16 A04_Value;
   public UInt16 A05_Index;
   public UInt32 A06_Length;
}
Цитата Сообщение от -VIRUS- Посмотреть сообщение
копируем структуру в память
Зачем два раза?
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,574
06.02.2018, 19:18
C#
1
2
3
4
5
6
7
8
9
10
        private static byte[] FillBytes<T>(T Buffer)
        {
            int size = Marshal.SizeOf(typeof(T));
            byte[] Ret = new byte[size];
            var ptr = Marshal.AllocHGlobal(size); // указатель
            Marshal.StructureToPtr(Buffer, ptr, false); // копируем структуру в память
            Marshal.Copy(ptr, Ret, 0, Ret.Length);
            Marshal.FreeHGlobal(ptr);
            return Ret;
        }
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public static byte[] GetBytes<T>(T str)
{
    int size = Marshal.SizeOf(str);
 
    byte[] arr = new byte[size];
 
    GCHandle h = default(GCHandle);
 
    try
    {
        h = GCHandle.Alloc(arr, GCHandleType.Pinned);
 
        Marshal.StructureToPtr<T>(str, h.AddrOfPinnedObject(), false);
    }
    finally
    {
        if (h.IsAllocated)
        {
            h.Free();
        }
    }
 
    return arr;
}
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
06.02.2018, 19:22
Можно же напрямую в массив писать, без дополнительного копирования:
C#
1
2
3
var handle = GCHandle.Alloc(Ret, GCHandleType.Pinned);
Marshal.StructureToPtr(Buffer, handle.AddrOfPinnedObject(), true);
handle.Free();
0
2 / 2 / 1
Регистрация: 07.12.2013
Сообщений: 83
06.02.2018, 19:22  [ТС]
Дык это, массив не корректен. 20байт. должен быть 15.
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
06.02.2018, 19:24
Цитата Сообщение от -VIRUS- Посмотреть сообщение
20байт. должен быть 15.
Ответ выше.
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,574
06.02.2018, 19:24
Почему 15? Если структура у вас 14 байт...
0
2 / 2 / 1
Регистрация: 07.12.2013
Сообщений: 83
06.02.2018, 19:26  [ТС]
2+4+1+2+2+4 эмм 15), или я чет не догоняю?
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,574
06.02.2018, 19:27
Точно, байт пропустил. Так и получается 15, если воспользоваться советом выше (я про Pack = 1).
0
2 / 2 / 1
Регистрация: 07.12.2013
Сообщений: 83
06.02.2018, 19:31  [ТС]
int size = Marshal.SizeOf(str);
возвращает 20; 0x14

Добавлено через 2 минуты
прикол в том что размер массива критичен, он далее передается API DeviceIoControl

Добавлено через 26 секунд
как убрать выравнивание?
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
06.02.2018, 19:32
Цитата Сообщение от -VIRUS- Посмотреть сообщение
возвращает 20
как убрать выравнивание?
Ответ все еще выше.
0
2 / 2 / 1
Регистрация: 07.12.2013
Сообщений: 83
06.02.2018, 19:35  [ТС]
Тьфу блин, спасибо вкурил.
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,574
06.02.2018, 19:44
Лучший ответ Сообщение было отмечено kolorotur как решение

Решение

А я все жду C# 7.3, там по идее вот такой код должен стать валидным
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
        private static unsafe T ToStruct<T>(this byte[] buf) where T : unmanaged
        {
            fixed (byte* ptr = buf)
            {
                return *(T*)ptr;
            }
        }
 
        private static unsafe byte[] FromStruct<T>(T str) where T : unmanaged
        {
            byte[] ret = new byte[sizeof(T)];
            fixed (byte* ptr = ret)
            {
                *(T*)ptr = str;
            }
            return ret;
        }
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
06.02.2018, 20:01
Цитата Сообщение от Someone007 Посмотреть сообщение
А я все жду C# 7.3
Подобное уже можно делать с пакетом Unsafe.
Правда, приходится отдельную либу тащить, но если уж очень надо...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
06.02.2018, 20:01
Помогаю со студенческими работами здесь

Аналоги System.Runtime.InteropServices.Marshal.GetActiveObject
Здравствуйте, подскажите если запущено 2 приложения, которыми нужно программно управлять, как мне получить их апи? Что то вроде... ...

Как избежать Marshal.Copy для отправки данных
У меня есть указатель IntPtr на масив байт и размер этого массива. Чтоб запихнуть его в сокет(отправить по сети) мне нужно сделать...

Использовние marshal.releasecomobject
Подскажите как узнать что к объекту, например, object a был применен метод Marshal.releasecomobject(a) Просто, у меня в программе в...

Marshal. Можно ли просмотреть значение памяти по IntPtr?
Собственно вот. Маршалю структуры и хочется на отладке посмотреть правильно прошел маршалинг или нет. Особенно это касается массивов и...

С#/Структуры вложенные/Marshal еще раз объясните?
Здравствуйте. Код примерно такой: ... public unsafe struct def_ { public short flag;


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru