简体   繁体   English

C程序中的联盟遇到麻烦

[英]Trouble with Unions in C program

I am working on a C program that uses a Union. 我正在开发一个使用Union的C程序。 The union definition is in FILE_A header file and looks like this... 联合定义在FILE_A头文件中,看起来像这样......

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

If I set the value of CurrentPosition.position in FILE_A.c and then call a function in FILE_B.c that uses the union, the data in the union is back to Zero. 如果我在FILE_A.c中设置CurrentPosition.position的值然后调用FILE_B.c中使用union的函数,则union中的数据将返回Zero。 This is demonstrated below. 这在下面说明。

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

Now, If I pass a long to SomeFunctionInFileB(long temp) and then store it into CurrentPosition.bytes within that function, and finally call WriteBytesToFlash(CurrentPosition.bytes[n]... it works just fine. 现在,如果我将一个long传递给SomeFunctionInFileB(long temp)然后将它存储到该函数中的CurrentPosition.bytes中,最后调用WriteBytesToFlash(CurrentPosition.bytes [n] ......它的工作正常。

It appears as though the CurrentPosition Union is not global. 似乎CurrentPosition Union不是全球性的。 So I tried changing the union definition in the header file to include the extern keyword like this... 所以我尝试更改头文件中的联合定义以包含像这样的extern关键字......

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

and then putting this in the source (.c) file... 然后把它放在源(.c)文件中......

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

but this causes a compile error that says: 但这会导致编译错误,说:

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

So what am I doing wrong? 那么我做错了什么? How do I make the union global? 如何使联盟全球化?

Is FILE_A.h really MotionControl.h ? FILE_A.h真的是MotionControl.h吗? If so I think the fix is to define a union type in the header: 如果是这样,我认为修复是在标头中定义一个联合类型:

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

And declare a global variable of that type elsewhere in a header file (maybe the same one): 并在头文件中的其他地方声明该类型的全局变量(可能是同一个):

extern xdata CurrentPosition;   // in a header file

Finally define the global variable in a C file exactly once . 最后在C文件中定义一次全局变量。 Maybe in file_a.c : 也许在file_a.c

xdata CurrentPosition;

Of course a better fix might be to pass the xdata variable you want to write out to flash to SomeFunctionInFileB() so you don't have to depend on a global variable, which are well known to be problematic when not very, very carefully used. 当然,一个更好的修复方法可能是将你要写出的xdata变量传递给flash到SomeFunctionInFileB()这样你就不必依赖一个全局变量,众所周知,当不是非常非常谨慎地使用它时会有问题。 。 And there seems to be no good reason to not pass the data as a parameter: 似乎没有充分的理由不将数据作为参数传递:

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

And call it like so: 并称之为:

int main.c(void)
{
    CurrentPosition.position = 12345;
    SomeFunctionInFileB( &CurrentPosition);
}

Ideally you need a typedef for the union and an extern declaration in FILE_A.h and the actual definition of the union in FILE_A.c. 理想情况下,你需要一个用于union的typedef和一个FILE_A.h中的extern 声明以及FILE_A.c中union的实际定义

- -

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

- -

You haven't instantiated the union. 你还没有实例化联盟。
You need : 你需要 :

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

If sizeof(long) is not 4, then endianess comes into play... 如果sizeof(long)不是4,那么endianess就会发挥作用......

consider 考虑

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM