C程序中的联盟遇到麻烦

时间:2010-05-04 19:45:59

标签: c global unions

我正在开发一个使用Union的C程序。联合定义在FILE_A头文件中,看起来像这样......

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

如果我在FILE_A.c中设置CurrentPosition.position的值然后调用FILE_B.c中使用union的函数,则union中的数据将返回Zero。这将在下面说明。

// 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 个答案:

答案 0 :(得分:7)

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变量传递给flash 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);
}

答案 1 :(得分:2)

理想情况下,你需要一个联合的typedef和FILE_A.h中的extern 声明以及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];
}

-

答案 2 :(得分:1)

您尚未实例化联盟 你需要:

// 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];
}

答案 3 :(得分:0)

如果sizeof(long)不是4,那么endianess就会发挥作用......

考虑

union{
   long position
   char bytes[sizeof long];
}