Проблема с Союзами в C-программе - PullRequest
3 голосов
/ 04 мая 2010

Я работаю над программой на C, которая использует Union. Определение объединения находится в заголовочном файле FILE_A и выглядит следующим образом ...

// FILE_A.h****************************************************
xdata union  
{
long position;
char bytes[4];
}CurrentPosition;

Если я установлю значение CurrentPosition.position в FILE_A.c, а затем вызову функцию в FILE_B.c, которая использует объединение, данные в объединении возвращаются к нулю. Это показано ниже.

// FILE_A.c****************************************************
int main.c(void)
{
    CurrentPosition.position = 12345;
    SomeFunctionInFileB();
}

// FILE_B.c****************************************************
void SomeFunctionInFileB(void)
{
    // After the following lines execute I see all zeros in the flash memory.
    WriteByteToFlash(CurrentPosition.bytes[0];
    WriteByteToFlash(CurrentPosition.bytes[1];
    WriteByteToFlash(CurrentPosition.bytes[2];
    WriteByteToFlash(CurrentPosition.bytes[3];
}

Теперь, если я передам long в SomeFunctionInFileB (long temp), а затем сохраню его в CurrentPosition.bytes внутри этой функции, и, наконец, вызову WriteBytesToFlash (CurrentPosition.bytes [n] ... это работает просто отлично.

Похоже, что CurrentPosition Union не является глобальным. Поэтому я попытался изменить определение объединения в заголовочном файле, включив в него ключевое слово extern, например ...

extern xdata union  
{
long position;
char bytes[4];
}CurrentPosition;

и затем поместить это в исходный файл (.c) ...

xdata union  
{
    long position;
    char bytes[4];
}CurrentPosition;

но это вызывает ошибку компиляции, которая говорит:

C:\SiLabs\Optec Programs\AgosRot\MotionControl.c:76: error 91: extern definition for 'CurrentPosition' mismatches with declaration. C:\SiLabs\Optec Programs\AgosRot\/MotionControl.h:48: error 177: previously defined here

Так что я делаю не так? Как сделать глобальный союз?

Ответы [ 4 ]

7 голосов
/ 04 мая 2010

Является ли FILE_A.h действительно MotionControl.h? Если это так, я думаю, что исправить это определить тип объединения в заголовке:

typedef
union xdata
{
    long position;
    char bytes[4];
} xdata;

И объявить глобальную переменную этого типа в другом месте заголовочного файла (возможно, того же самого):

extern xdata CurrentPosition;   // in a header file

Наконец, определите глобальную переменную в файле C ровно один раз . Может быть, в file_a.c:

xdata CurrentPosition;

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

// in a header file
void SomeFunctionInFileB( xdata const* pPosition);


void SomeFunctionInFileB( xdata const* pPosition)
{
    // After the following lines execute I see all zeros in the flash memory.
    WriteByteToFlash(pPosition->bytes[0];
    WriteByteToFlash(pPosition->bytes[1];
    WriteByteToFlash(pPosition->bytes[2];
    WriteByteToFlash(pPosition->bytes[3];
}

И назовите это так:

int main.c(void)
{
    CurrentPosition.position = 12345;
    SomeFunctionInFileB( &CurrentPosition);
}
2 голосов
/ 04 мая 2010

В идеале вам нужна typedef для объединения и extern объявление в FILE_A.h и фактическое определение объединения в FILE_A.c.

-

// FILE_A.h

typedef union  
{
    long position;
    char bytes[4];
} Position;

extern Position CurrentPosition; // declaration

-

// FILE_A.c

#include "FILE_A.h"

Position CurrentPosition; // definition

int main(void)
{
    CurrentPosition.position = 12345;
    SomeFunctionInFileB();
    return 0;
}

-

// FILE_B.c

#include "FILE_A.h"

void SomeFunctionInFileB(void)
{
    // now there will be valid data in the flash memory.
    WriteByteToFlash(cp.bytes[0];
    WriteByteToFlash(cp.bytes[1];
    WriteByteToFlash(cp.bytes[2];
    WriteByteToFlash(cp.bytes[3];
}

-

1 голос
/ 04 мая 2010

Вы не создали экземпляр объединения.
Вам нужно:

// FILE_A.c****************************************************

#include "File_a.h"
CurrentPosition cp;
int main(void)
{
    cp.position = 12345;
    SomeFunctionInFileB();
}

// FILE_B.c****************************************************
#include "File_a.h"
extern CurrentPosition cp;
void SomeFunctionInFileB(void)
{
    // now there will be valid data in the flash memory.
    WriteByteToFlash(cp.bytes[0];
    WriteByteToFlash(cp.bytes[1];
    WriteByteToFlash(cp.bytes[2];
    WriteByteToFlash(cp.bytes[3];
}
0 голосов
/ 05 мая 2010

Если sizeof(long) не равно 4, тогда в игру вступает endianess ...

рассмотреть

union{
   long position
   char bytes[sizeof long];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...