Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.61/18: Рейтинг темы: голосов - 18, средняя оценка - 4.61
28 / 28 / 2
Регистрация: 24.01.2013
Сообщений: 183

Маршалинг структур. Размер string

04.07.2013, 23:16. Показов 3374. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
В общем начал разбираться с маршалингом структур. правда некоторые моменты непонятны. например

Вот я делаю так

C#
1
2
3
4
5
6
7
8
9
10
11
12
    [StructLayout(LayoutKind.Explicit,Size=141)]
    public struct TableModel
    {
        [FieldOffset(0)]
        public long id; // 8
        [FieldOffset(8)]
        public byte action; // 1
        [FieldOffset(9)]
        public int key; // 4
        [FieldOffset(13)]
        public string nameRu;
    }
возможная проблема - выравнивание с чем я пока не особо разбираюсь

да и никак не пойму как указать string - чтобы он использовал 128 байт в случаи ошибки указывал на переполнение ...
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
04.07.2013, 23:16
Ответы с готовыми решениями:

Маршалинг структур: динамическое управление размером
Решил изучить как с помощью средств c# передавать структуры. Нашел способы преобразования структур в массив байт с помощью Marashal. Вот...

Маршалинг string
Возник затуп при обращении к dll на с++. Как связан .net'овский string и CHAR,WCHAR,LPSTR,LPCSTR,LPWSTR,LPCWSTR? Как будет маршалинг...

Маршалинг и структура
Добрый день, товарищи. Есть библиотека С++, в которой имеется структура и метод с нею работающий: struct MyCPPStruct { char...

6
Почетный модератор
Эксперт .NET
 Аватар для NickoTin
8729 / 3681 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
04.07.2013, 23:58
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
/* unsafe */public struct TableModel
{
    public long id;
    public byte action;
    public int key;
    // --- (1)
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
    public string nameRu;
    // --- (2)
    // [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
    // public char[] nameRu;
    // --- (3)
    // public fixed sbyte /* char */ nameRu[128];
}
В первом (1) случае при маршалинге структуры строка будет иметь размер 127 символов (127 байт в ANSI или 254 байта в Unicode) плюс завершающий NULL символ (\0 или \0\0). Проверок на переполнение нет, строка будет просто обрезана => нужно писать метод для проверки.
Во втором (2) случае NULL символа не будет, но нужно будет писать метод по преобразованию string в char[] и обратно, ну и проверку на переполнение выполнять за компанию.
В третьем (3) случае используется неуправляемый код, суть та же что и во втором случае, только тут нужно работать с unsafe кодом и использовать sbyte для однобайтовых кодировок и char для 2-байтовых.
1
28 / 28 / 2
Регистрация: 24.01.2013
Сообщений: 183
05.07.2013, 00:30  [ТС]
NickoTin,
Спасибо, а как получить размер в тех или иных случаях. Использую Marshal.SizeOf - результат не выдает - все времяопределяет ошибку
0
Почетный модератор
Эксперт .NET
 Аватар для NickoTin
8729 / 3681 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
05.07.2013, 00:34
Цитата Сообщение от ayrat Посмотреть сообщение
результат не выдает - все времяопределяет ошибку
Значит как-то не так используете.
C#
1
2
        var tm = new TableModel();
        var sz = Marshal.SizeOf( tm ); // размер структуры TableModel или Marshal.SizeOf( typeof(TableModel) );
з.ы. Поправил третий пункт в предыдущем сообщении.
1
28 / 28 / 2
Регистрация: 24.01.2013
Сообщений: 183
05.07.2013, 00:49  [ТС]
Я немного о другом. Я хочу выделить string 128 байт, а когда вызываю
C#
1
2
var tm = new TableModel();
var sz = Marshal.SizeOf(tm.nameRu);
- таким образом хочу получить размер string то есть 128 - или я творю полную ерунду? если нет то как получить

Добавлено через 6 минут
И ещё вопрос когда делаю так

C#
1
2
3
4
5
6
7
8
9
10
11
12
[StructLayout(LayoutKind.Explicit,Size=141)]
    public struct TableModel
    {
        [FieldOffset(0)]
        public long id; // 8
        [FieldOffset(8)]
        public byte action; // 1
        [FieldOffset(9)]
        public int key; // 4
        [FieldOffset(13)]
        public string nameRu;
    }
- выдает ошибку Не удалось загрузить тип "ConsoleApplication1.TableModel" из сборки "ConsoleApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", так как он содержит поле объекта со смещением 13, которое неверно выровнено или перекрыто полем, не представляющим объект.

Заранее извините понимаю что пока я недопонимаю маршалинг, но у меня есть цель чтобы сделать такую структуру чтобы мне не пришлось писать дополнительные моменты указывая размеры тех или иных столбцов в другом классе. Хочу чтобы это все было отражено в структуре и я мог получать в том числе и для проверки правильные ли я данные ввожу.

Добавлено через 1 минуту
Есть у меня конечно ужасный способ делать все так как я хочу, но он безобразен.

C#
1
2
3
4
5
6
7
8
9
10
11
    public class CountryTableModel
    {
        public int nameSize { get { return 64; } }
        public string name { get; set; }
        public int keySize { get { return 4; } }
        public int key { get; set; }
        public int actionSize { get { return 1; } }
        public byte action { get; set; }
        public int idSize { get { return 8; } }
        public long id { get; set; }
    }
0
Почетный модератор
Эксперт .NET
 Аватар для NickoTin
8729 / 3681 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
05.07.2013, 00:57
Ерунду.

На ум приходит 3 варианта:
  1. Использовать константу и не заморачиваться:
    C#
    1
    2
    3
    
    private const int NAME_RU_SIZE = 128;
    ...
    [MarshalAs( UnmanagedType.ByValTStr, SizeConst = NAME_RU_SIZE )]
  2. Расчет через смещения. Считаем смещение нужного поля относительно следующего:
    C#
    1
    
    Marshal.OffsetOf( typeof( TableModel ), "field_after_required" ) - Marshal.OffsetOf( typeof( TableModel ), "required_field" )
    Но т.к. у нас поле nameRu последнее тогда отнимаем его смещение от размера структуры:
    C#
    1
    
    Marshal.SizeOf( tm ) - Marshal.OffsetOf( typeof( TableModel ), "nameRu" ).ToInt32();
  3. Используя рефлексию читаем нужные атрибуты поля (тормозной способ, хотя можно один раз прочитать и сохранить в кэш).
1
28 / 28 / 2
Регистрация: 24.01.2013
Сообщений: 183
05.07.2013, 01:24  [ТС]
NickoTin,
Да в принципе совсем разобрался. использование [FieldOffset(148)] - офсетов -решает все проблемы, а точнее делает код симпатичнее. и можно получить спокойно размеры, правда с некоторыми вычислениями. Ошибка была в том что тип byte всегда имеет смещение в + 8, а не +1 (если исходить из логики) (поэтому иногда думаю вообще стоит ли использовать byte)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
05.07.2013, 01:24
Помогаю со студенческими работами здесь

Маршалинг структуры C# --> C
В неуправляемом коде (bla.dll) есть структура: typedef struct { ULONG32 a; UINT8 b; UINT8 c; UINT16 d; ...

Маршалинг C++ wchar_t** в C#
Доброго времени суток! Столкнулся со следующей задачей. Есть библиотека, в библиотеке есть функция, которую необходимо вызвать в C#...

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

Маршалинг Waveform Audio
Привет. Возникла необходимость сделать wrapper для c# библиотеки Windows Waveform Audio. Пока работаю пока только с одной структурой...

Что такое маршалинг?
Можете по простому объяснить что это такое. И пример, где это используется и для чего он нужен.


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели 8ATzM_2aurI
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2. Задача: запретить редактирование документа, если он открыт у другого пользователя. / / . . .
Система безопасности+живучести для сервера-слоя интернета (сети). Двойная привязка.
Hrethgir 08.04.2026
Далее были размышления о системе безопасности. Сообщения с наклонным текстом - мои. А как нам будет можно проверить, что ссылка наша, а не подделана хулиганами, которая выбросит на другую ветку и. . .
Модель ЗдрввоСохранения 7: больше работников, больше ресурсов.
anaschu 08.04.2026
работников и заданий может быть сколько угодно, но настроено всё так, что используется пока что только 20% kYBz3eJf3jQ
Дальние перспективы сервера - слоя сети с космологическим дизайном интефейса карты и логики.
Hrethgir 07.04.2026
Дальнейшее ближайшее планирование вывело к размышлениям над дальними перспективами. И вот тут может быть даже будут нужны оценки специалистов, так как в дальних перспективах всё может очень сильно. . .
Горе от ума
kumehtar 07.04.2026
Эта мне ментальная установка, что вот прямо сейчас, мол, мне для полного счастья не хватает (нужное вписать), и когда я этого достигну - тогда и полный кайф. Одна из самых сильных ловушек на пути. . . .
Использование значений реквизитов справочника в документе, с определенными условиями и правами
Maks 07.04.2026
1. Контроль срока действия договора Алгоритм из решения ниже реализован на примере нетипового документа "ЗаявкаНаРаботу", разработанного в конфигурации КА2. Задача: уведомлять пользователя, если. . .
Доступность команды формы по условию
Maks 07.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: сделать доступной кнопку (команда формы "ЗавершитьСписание") при. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru