|
Union c внешними (external) переменными, подскажите, как сделать |
|
|
|
Apr 14 2010, 12:09
|
Участник

Группа: Свой
Сообщений: 60
Регистрация: 4-04-07
Пользователь №: 26 770

|
Здравствуйте. Кратко опишу проблему: В программе есть два модуля: один низкоуровневый - "lowlevel.c" и основной модуль "main.c". В модуле "lowlevel.c" объявлен некий буфер Код char buffer[10]; и модуль умеет с ним работать, например, посылать данные из этого буфера на внешнее устройство. Этому модулю нет дела до того, что означает каждый байт этого буфера, его дело - передать данные. На самом деле каждый байт из этого буфера имеет особый смысл: заголовок, управляющие поля, данные, контрольная сумма. Хочется, чтобы основной модуль мог работать с этим буфером как со структурой, т.е. что-то вроде того: Код union { char buffer[10]; struct { char NT; char mask; char event; char blok; char echo; char data[3]; int crc; }; } LO_TRBuf; Однако, всё осложняется тем, что элементы структуры описаны с модуле "main.c", а буфер находится в "lowlevel.c". Пробовал использовать директиву "extern" в разных местах, но добиться желаемого не удалось. Можно, конечно перенести описание структуры в "lowlevel.h", но это будет неправильно с точки зрения инкапсуляции данных. Посоветуйте какое-либо решение?
|
|
|
|
|
 |
Ответов
|
Apr 14 2010, 12:30
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Работать с указателями. Код typedef struct { char NT; char mask; char event; char blok; char echo; char data[3]; int crc; } mystruct; extern char *buffer; void test() { mystruct *pData = (mystruct *)buffer; pData->NT = 12; pData->echo = 'A'; } Если процессор требует выровненного доступа (ARM, MSP) - при объявлении структуры указать, что структура упакована - #pragma pack, __attribute__((packed))
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Apr 15 2010, 09:37
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Цитата(Сергей Борщ @ Apr 14 2010, 16:45)  Работать с указателями. Код typedef struct { char NT; ... int crc; } mystruct; extern char *buffer; void test() { mystruct *pData = (mystruct *)buffer; pData->NT = 12; pData->echo = 'A'; } Тут ошибка - должно быть extern char buffer[];А если сделать так - Код typedef struct { char NT; ... int crc; } mystruct; extern char buffer[]; #define pData ((mystruct*)buffer) void test() { pData->NT = 12; pData->echo = 'A'; } то и лишних поинтеров и сложений скорее всего не будет (если компилятор достаточно умный)
|
|
|
|
|
Apr 15 2010, 10:30
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Цитата(XVR @ Apr 15 2010, 14:32)  extern char* buffer; - означает, что в переменной buffer лежит адрес массива, а она сама является указателем. extern char buffer[]; - означает, что buffer САМА является массивом, т.е. массив лежит начиная с ее адреса и далее. Ничего это не означает. Можно написать char* buffer; а потом buffer[i] выберет нужный элемент массива buffer[] - это фактически указатель на первый (нулевой) элемент
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Apr 15 2010, 11:11
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Цитата(MrYuran @ Apr 15 2010, 14:45)  Ничего это не означает. Означает. Цитата Можно написать char* buffer; а потом buffer[i] выберет нужный элемент массива buffer[] - это фактически указатель на первый (нулевой) элемент Можно, но не для extern: Пример для неверующих: t1.cpp Код #include <stdio.h>
char* s1="abc"; char s2[]="abc";
void t();
int main() { printf("s1: %p %s\n",s1,s1); printf("s2: %p\n",s2); printf(" %s\n",s2); t(); return 0; } t2.cpp Код #include <stdio.h>
extern char* s1; extern char* s2;
void t() { printf("e s1: %p %s\n",s1,s1); printf("e s2: %p\n",s2); printf(" %s\n",s2); } Сборка: g++ t1.cpp t2.cpp Запуск: Цитата s1: 0x4006ec abc s2: 0x500a68 abc e s1: 0x4006ec abc e s2: 0x636261 Segmentation fault Обратите внимание на выделенные строки, а особенно на указатель со значением 0x636261 (в ASCII это будет cba, ничего не напоминает?)
|
|
|
|
Сообщений в этой теме
Dmitro25 Union c внешними (external) переменными Apr 14 2010, 12:09 MrYuran Цитата(Dmitro25 @ Apr 14 2010, 16:24) Одн... Apr 14 2010, 12:15 Dmitro25 2MrYuran:
Она у меня и так описана в main.c. А под... Apr 14 2010, 12:18    Сергей Борщ Цитата(XVR @ Apr 15 2010, 12:32) В этом к... Apr 15 2010, 11:16 Dmitro25 2Сергей Борщ
Спасибо за ответ. Я уже думал о таком... Apr 14 2010, 12:46 Палыч Зачем в union тащить какой-то extern? Нужно в моду... Apr 14 2010, 13:00 zltigo Цитата(Dmitro25 @ Apr 14 2010, 15:01) Но ... Apr 14 2010, 13:11 Сергей Борщ Цитата(Dmitro25 @ Apr 14 2010, 15:01) Но ... Apr 14 2010, 20:10 baralgin Или так: разместить объект структуры(не массив) в ... Apr 14 2010, 13:06 Dmitro25 2Палыч
2baralgin
Я просто для инкапсуляции хотел, ... Apr 14 2010, 13:52 _Pasha Цитата(Dmitro25 @ Apr 14 2010, 17:07) я у... Apr 14 2010, 13:56 Палыч Цитата(Dmitro25 @ Apr 14 2010, 17:07) Я п... Apr 14 2010, 15:15 baralgin Dmitro25 Пишем в lowlevel функцию типа "void*... Apr 14 2010, 14:09 Dmitro25 2baralgin
2Сергей Борщ
Спасибо, я, наверное, что-т... Apr 15 2010, 05:56 Dmitro25 XVR
Спасибо за подсказку.
Ваш вариант с преобразо... Apr 16 2010, 04:32
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|