Форум программистов, компьютерный форум CyberForum.ru

Visual C++

Войти
Регистрация
Восстановить пароль
 
 
Paulie
Айхрень...
306 / 174 / 4
Регистрация: 02.06.2009
Сообщений: 1,078
#1

Использование #pragma pack(push,1)... pack(pop) - Visual C++

27.11.2009, 11:58. Просмотров 39950. Ответов 51
Метки нет (Все метки)

Добрый день, товарищи.

Задался вопросом о записи в файл структур данных, читал читал в интернете много интересного. Наткнулся на статью, где описан такой вот вариант задания структур:

C++
1
2
3
#pragma pack (push, 1)
deftype struct {...}
#pragma pack ( pop)
Но почему-то автор не рекомендует использовать, вот я не совсем понял этот момент. Он описал как-то расплывчато пример, когда это не сработает...

Я использую структуру с уже определёнными размерами параметров, так что её размер не будет меняться во времени, проверил, у меня всё работает.

Но почему же автор всё-таки не рекомендует это использовать???
Может есть ещё интересные варианты?

Для записи в файл использую CreateFile, WriteFile (MSDN->System services->File services->file systems->file management)...

Заранее благодарю.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
27.11.2009, 11:58     Использование #pragma pack(push,1)... pack(pop)
Посмотрите здесь:

#pragma - Visual C++
Научите пользоваться этой штуковиной. Интересует для начала что означает само слово pragma для VS и всё что можно сделать через неё.

Pragma comment() - Visual C++
Добрый день! Подскажите, пожалуйста, как быть, если компановщик игнорирует запись #pragma comment(exestr, L"My Programs"). VS 2010 Pro. Мне...

что такое #pragma once? - Visual C++
??????????

Русские символы NT 4.0+Service pack 6 + Option pack + MS SQL7.0 с СР1251 - C# ASP.NET
Помогите пожалуйста!!!!!! имею NT 4.0+Service pack 6 + Option pack + MS SQL7.0 с СР1251 Выполняю код с подключением к базе через ODBC...

Pack() [function.pack]: Type H: illegal hex digit m in - PHP
Возникла довольно странная проблема, при загрузке страницы вылезает Warning: pack() : Type H: illegal hex digit m in, в чем может быть...

Сделать так чтобы если вводится push выполнялась функция push, если pop то pop - Python
Помогите пожалуйста с данным вопросом: например у меня есть список и несколько возможных с ним операций (например push - добавить элемент...

push и pop - C# ASP.NET
У меня возникла странная проблема. Мы создали сайт на основе системы управления, которой пользовались не один раз. Все сайты нормально...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
xAtom
914 / 739 / 60
Регистрация: 09.12.2010
Сообщений: 1,346
Записей в блоге: 1
11.04.2011, 20:40     Использование #pragma pack(push,1)... pack(pop) #21
Почему прикладная программа не работает с железом работает ещё как но использует удобные функции системы а не ввиде 0FEF00E7h абстракцию создаёт понятную нам, парадигма систем облегчение программироавние железа, а не купание в байт кодах. Так же можно сказать про нас что мы с миром не контачим непосредственно а купаемся в абстракциях мозга ЦНС электро-импульсов то что не надо здесь разводить суть вещей...
slowCheetah
11 / 11 / 1
Регистрация: 18.07.2009
Сообщений: 123
11.04.2011, 20:56     Использование #pragma pack(push,1)... pack(pop) #22
Цитата Сообщение от Evg Посмотреть сообщение
Вообще говоря, любой адрес выровнен на 1 байт. А твои слова сильно смахивают на испорченный телефон. Не говоря уж о том, что напрямую с железками работает только ОС, а не пользовательская программа
бла бла бла, какой ты опять умный, опять очередной твой такой же пост

про то, что человек, занимающийся драйверами использует эти приемы в прикладных программах у меня не было и слова - заметь

использует он эти директивы, когда работает с сетью, а драйвера он пишет для сетевых карт, реализует сетевые протоколы на низком уровне и тп и мне советует их использовать в этих же случаях (если когда придется), и что даже в прикладных программах, отправляющих что-то по сети, лучше тоже пользоваться этими директивами

что не пост от Evg, то всегда попытка съязвить

и когда я писал предыдущее собщение, то по-любому был уверен, что найдется хотя бы 1 человек, который несмотря на то, что топику уже 2 года, все равно возьмет и ответит - и о да, конечно же я был уверен на 100 %, что это будет Evg - ведь он обязательно найдет за что зацепится и обязательно покажет свою крутость
Evg
Эксперт CАвтор FAQ
17462 / 5700 / 361
Регистрация: 30.03.2009
Сообщений: 15,647
Записей в блоге: 26
11.04.2011, 21:58     Использование #pragma pack(push,1)... pack(pop) #23
__beginner__, если отбросить флуд и эмоции, то что ты этим хотел сказать? И заодно поясни, что имелось в виду под "прям обязательно нужно выравнивать по 1 байту", если уж тебе так хочется почесать языком
snake32
1376 / 1019 / 136
Регистрация: 26.02.2009
Сообщений: 3,766
Записей в блоге: 5
05.12.2011, 17:04     Использование #pragma pack(push,1)... pack(pop) #24
Цитата Сообщение от Paulie Посмотреть сообщение
если взять проекцию на Делфи, то диреткива #pragma pack делает что-то наподобие, как и record packed в Делфи? Или второе - это выравнивание структуры, а в сях - выравнивание полей, как сказал уважаемый Evg, ну это так, чисто интерес, вспомнилось былое прошлое...
В делфях record packed выравнивает поля структуры как и #pragma pack 1
Кстати есть ещё выравнивание в массиве packed array
Pure
228 / 49 / 2
Регистрация: 13.03.2012
Сообщений: 453
Записей в блоге: 7
28.05.2012, 12:58     Использование #pragma pack(push,1)... pack(pop) #25
коммент не убрал...бывает..
programina
1914 / 599 / 37
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
28.05.2012, 20:22     Использование #pragma pack(push,1)... pack(pop) #26
Цитата Сообщение от Evg Посмотреть сообщение
А вопрос не в оптимизации структуры. Вопрос в том, чтобы правильно расписать структуру, чтобы она один в один ложилась на формат бинарного файла. Т.е. если в бинарном файле заголовок состоит из трёх полей размерами в один, четыре и два байта, идущих подряд друг за другом, то можно написать структуру

C
1
2
3
4
5
6
7
8
#pragma pack (push, 1)
struct
{
  char f1;
  int f2;
  short f3;
};
#pragma pack (pop)
и потом целиком экземпляр этой структуры одной операцией записывать или считывать в файл. sizoef от такой структуры будет равен 7. Стандартными средствами языка по-нормальному ты это не сделаешь. Можно только описать структуру, а потом читать-писать каждое поле в отдельности
Недавно столкнулась с такой проблемой: в Линуксе не правильно отображались данные заголовка .bmp рисунка, в виндовс я пользовалась wingdi.h и все работало, и только потом заметила, что структура заключена в данные директивы...
novi4ok
551 / 504 / 8
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
28.05.2012, 20:26     Использование #pragma pack(push,1)... pack(pop) #27
а что внутри структуры? другие структуры, внутри которых - другие и т.д.?

все работает, причем надежно, как бомба. если структуру, которую вы привели, "не заключить в данные директивы", то она будет занимать 10 байт (4+4+2), а если заключить - то 7 (1+4+2). и больше ничего за этим не скрывается. тот, кто хочет позднее обратиться к любому полю кроме f1 не по имени, а по смещению, должен точно знать, как структура была определена: "в директивах" или без.
Evg
Эксперт CАвтор FAQ
17462 / 5700 / 361
Регистрация: 30.03.2009
Сообщений: 15,647
Записей в блоге: 26
28.05.2012, 20:32     Использование #pragma pack(push,1)... pack(pop) #28
Цитата Сообщение от novi4ok Посмотреть сообщение
а что внутри структуры? другие структуры, внутри которых - другие и т.д.
http://www.cyberforum.ru/blogs/203892/blog441.html
novi4ok
551 / 504 / 8
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
28.05.2012, 20:43     Использование #pragma pack(push,1)... pack(pop) #29
если продолжать, то нужно также уточнить, что означает
в Линуксе не правильно отображались данные заголовка .bmp рисунка
хотя в ссылке вроде УРА написано, так что автор нам просто причину может назвать в деталях.
Evg
Эксперт CАвтор FAQ
17462 / 5700 / 361
Регистрация: 30.03.2009
Сообщений: 15,647
Записей в блоге: 26
28.05.2012, 20:48     Использование #pragma pack(push,1)... pack(pop) #30
Цитата Сообщение от novi4ok Посмотреть сообщение
так что автор нам просто причину может назвать в деталях
Читатель может самостоятельно ответить на данный вопрос, если немного подумает
novi4ok
551 / 504 / 8
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
28.05.2012, 21:10     Использование #pragma pack(push,1)... pack(pop) #31
я так понял, что если писатель написал УРА, то по ссылке - работающий код?
programina
1914 / 599 / 37
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
28.05.2012, 21:11     Использование #pragma pack(push,1)... pack(pop) #32
Наглядный пример для всех кто сомневается
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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <stdio.h>
 
#pragma pack(push,1)
struct BITMAPFILEHEADER_PRAGMA {
    unsigned short  bfType;
    unsigned long   bfSize;
    unsigned short  bfReserved1;
    unsigned short  bfReserved2;
    unsigned long   bfOffBits;
};
#pragma pack(pop)
 
struct BITMAPFILEHEADER_NOPRAGMA{
    unsigned short  bfType;
    unsigned long   bfSize;
    unsigned short  bfReserved1;
    unsigned short  bfReserved2;
    unsigned long   bfOffBits;
};
 
 
int main()
{
    BITMAPFILEHEADER_PRAGMA    pragma;
    BITMAPFILEHEADER_NOPRAGMA  nopragma;
    FILE                        *fin;
 
    printf("Действительный размер файла: 9270 байт\n");
 
    fin = fopen("picture1.bmp","rb+");
    fread( &pragma, sizeof(BITMAPFILEHEADER_PRAGMA), 1, fin );
    printf("bfSize c #pragma:\t%ld\n", pragma.bfSize);
    fclose(fin);
 
    fin = fopen("picture1.bmp","rb+");
    fread( &nopragma, sizeof(BITMAPFILEHEADER_NOPRAGMA), 1, fin );
    printf("bfSize без #pragma:\t%ld\n", nopragma.bfSize);
    fclose(fin);
 
    return 0;
}
Миниатюры
Использование #pragma pack(push,1)... pack(pop)  
Evg
Эксперт CАвтор FAQ
17462 / 5700 / 361
Регистрация: 30.03.2009
Сообщений: 15,647
Записей в блоге: 26
28.05.2012, 21:22     Использование #pragma pack(push,1)... pack(pop) #33
Цитата Сообщение от novi4ok Посмотреть сообщение
я так понял, что если писатель написал УРА, то по ссылке - работающий код?
А что мешает взять да проверить?
programina
1914 / 599 / 37
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
28.05.2012, 22:02     Использование #pragma pack(push,1)... pack(pop) #34
Цитата Сообщение от novi4ok Посмотреть сообщение
хотя в ссылке вроде УРА написано, так что автор нам просто причину может назвать в деталях.
в линуксе не используется WinAPI

PS: хотя может быть кто-то и использует
novi4ok
551 / 504 / 8
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
28.05.2012, 23:34     Использование #pragma pack(push,1)... pack(pop) #35
мы, мне кажется, все трое "говорим параллельно". я не понимаю вообще, в чем проблема и что нужно проверять, при чем здесь winapi в линухе и пр. стою на шланге, короче, sorry ...

все люди действительно умерли, потому что ели огурци?
programina
1914 / 599 / 37
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
29.05.2012, 06:01     Использование #pragma pack(push,1)... pack(pop) #36
Цитата Сообщение от programina Посмотреть сообщение
в Линуксе не правильно отображались данные заголовка .bmp рисунка
Дело в том, что они всеравно неправильно отображаются, потомучто при попытке открыть файл, кот. в виндовс отобразился правильно, в линуксе, отобразится неправильно.
Миниатюры
Использование #pragma pack(push,1)... pack(pop)   Использование #pragma pack(push,1)... pack(pop)  
Evg
Эксперт CАвтор FAQ
17462 / 5700 / 361
Регистрация: 30.03.2009
Сообщений: 15,647
Записей в блоге: 26
29.05.2012, 08:51     Использование #pragma pack(push,1)... pack(pop) #37
Думаю, что у тебя 32-битная винда и 64-битный линукс. Либо наоборот. В таких случаях когда видишь разные результаты, то первым делом надо смотреть за использованием типа long, т.к. он 32-битный в режиме 32 и 64-битный в режиме 64. Вообще для программы, которая должна работать в режиме 32 и 64, описывая одинаково оду и ту же структуру данных, использование long'а недопустимо. Вернее, использовать можно, но только под макросами

Добавлено через 1 минуту
В печать помимо полей нужно распечатать sizeof твоей структуры

Добавлено через 38 минут
Один из способов выяснения смещений полей внутри структуры - это использование макроса, обычно его называют OFFSETOF (или всякие вариации на эту тему типа __OFFSETOF, __offsetof и т.п.). Результатом работы макроса будет байтовое смещение заданного поля внутри заданной структуры или объединения

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
25
26
27
28
29
30
31
32
33
34
#include <stdio.h>
 
#define OFFSETOF(_type, _field) \
 ((int) (((char*)&((_type *)0)->_field) - ((char*)0)))
 
struct s1
{
  short x;
  int y;
  char z;
};
 
struct s2
{
  char a;
  struct s1 b;
};
 
 
int
main (void)
{
  printf ("%d\n", OFFSETOF (struct s1, x));
  printf ("%d\n", OFFSETOF (struct s1, y));
  printf ("%d\n", OFFSETOF (struct s1, z));
 
  printf ("%d\n", OFFSETOF (struct s2, a));
  printf ("%d\n", OFFSETOF (struct s2, b));
  printf ("%d\n", OFFSETOF (struct s2, b.x));
  printf ("%d\n", OFFSETOF (struct s2, b.y));
  printf ("%d\n", OFFSETOF (struct s2, b.z));
 
  return 0;
}
programina
1914 / 599 / 37
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
29.05.2012, 11:20     Использование #pragma pack(push,1)... pack(pop) #38
Evg, спасибо большое, у меня действительно 32-битный виндовс 7 и 64-битный линукс минт (вы телепат?)

PS: обязательно оставлю отзыв, но чуть позже
PPS: сижу значит в блогах и читаю всякие записи, и попадается мне ваша запись про директивы, но там еще не написано про #pragma, уже хотела оставить коммент с просьбой рассказать про эту прагму, но в последний момент передумала и зашла в гугл, который выдал эту тему
Evg
Эксперт CАвтор FAQ
17462 / 5700 / 361
Регистрация: 30.03.2009
Сообщений: 15,647
Записей в блоге: 26
29.05.2012, 11:25     Использование #pragma pack(push,1)... pack(pop) #39
Цитата Сообщение от programina Посмотреть сообщение
вы телепат?
Это называется "experience". Когда наступаешь на грабли, то потом их видишь издалека

Цитата Сообщение от programina Посмотреть сообщение
запись про директивы, но там еще не написано про #pragma
Статья про препроцессорные директивы. #pragma к ним не относится
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.05.2012, 11:27     Использование #pragma pack(push,1)... pack(pop)
Еще ссылки по теме:

Push, Pop - Assembler
Вот такое задание: F=Ʃ от 1 до 5 f (Ai) A1=2 Ai+1=Ai+2 Ai=(3*A)+(C/D). Нужно записать эту формулу в ассемблере с помощью Push, Pop...

Функции pop и push - C++
Здравствуйте, есть код, решающий задачу. В нем есть стандартные функции push и pop. Как можно расписать функции подробно pop и push?...

Верна ли реализация push/pop? - C (СИ)
Правильный ли у меня ход мыслей при написании кода, на тему реализации стека? #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include...

Работа с push/pop в стеке - C#
Здравствуйте, я тут столкнулся с проблемой, не могу понять, как работать со стеком. Ниже приведу код, чтобы показать ситуацию, просто для...

PUSH/POP vs MOV из памяти - Программирование
Какой из двух ниже перечисленных примеров занимает меньше процессорного времени (тактов) ? 1: @@: PUSH ESI ;тут некий код POP...


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

Или воспользуйтесь поиском по форуму:
novi4ok
551 / 504 / 8
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
29.05.2012, 11:27     Использование #pragma pack(push,1)... pack(pop) #40
теперь все ясно. но я бы, если бы передо мной стояла такая задача, начал бы не с того, чтобы "немножко подумать", а с того, "как бы это увидеть". т.е. создал бы такую структуру в обеих системах и вывел бы memory dump. и все увидел бы очень быстро.
Yandex
Объявления
29.05.2012, 11:27     Использование #pragma pack(push,1)... pack(pop)
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru