реклама на сайте
подробности

 
 
> Union c внешними (external) переменными, подскажите, как сделать
Dmitro25
сообщение Apr 14 2010, 12:09
Сообщение #1


Участник
*

Группа: Свой
Сообщений: 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", но это будет неправильно с точки зрения инкапсуляции данных.
Посоветуйте какое-либо решение?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Сергей Борщ
сообщение Apr 14 2010, 12:30
Сообщение #2


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post
XVR
сообщение Apr 15 2010, 09:37
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 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';
}
то и лишних поинтеров и сложений скорее всего не будет (если компилятор достаточно умный)
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Apr 15 2010, 09:38
Сообщение #4


Беспросветный оптимист
******

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



Цитата(XVR @ Apr 15 2010, 13:52) *
Тут ошибка - должно быть extern char buffer[];

Без разницы.
Имя массива - уже указатель.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
XVR
сообщение Apr 15 2010, 10:17
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Цитата(MrYuran @ Apr 15 2010, 13:53) *
Без разницы.
Имя массива - уже указатель.
В этом контексте - нет. Результаты будут разные:
extern char* buffer; - означает, что в переменной buffer лежит адрес массива, а она сама является указателем.
extern char buffer[]; - означает, что buffer САМА является массивом, т.е. массив лежит начиная с ее адреса и далее.
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Apr 15 2010, 10:30
Сообщение #6


Беспросветный оптимист
******

Группа: Свой
Сообщений: 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 =)
Go to the top of the page
 
+Quote Post
XVR
сообщение Apr 15 2010, 11:11
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 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, ничего не напоминает?)
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- 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


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 30th July 2025 - 20:10
Рейтинг@Mail.ru


Страница сгенерированна за 0.01461 секунд с 7
ELECTRONIX ©2004-2016