我可以从PIC C18中的main.c访问source.c中的并集吗?

时间:2018-12-05 09:10:46

标签: c unions extern

我处于一个包含几个元素的匿名结构的位置。为了按索引访问它们,我将它们放在了一个联合体中,如下所示:

union
{
    struct
    {
        unsigned char COMMAND;      //STRUCT_ARRAY[0]
        unsigned char ADDR_H;       //STRUCT_ARRAY[1]
        unsigned char ADDR_M;       //STRUCT_ARRAY[2]
        unsigned char ADDR_L;       //STRUCT_ARRAY[3]
        unsigned char DATA;         //STRUCT_ARRAY[4]
        unsigned char CHECKSUM;     //STRUCT_ARRAY[5]
    };
    unsigned char STRUCT_ARRAY[6];
    //all of the struct members can be accessed from STRUCT_ARRAY by index
}MY_UNION;

此联合当前位于文件source.c中。我需要从main.c访问它。我有两个文件都包含的标头,我们称其为header.h

如何定期从source.c修改main.c中的ADDR_HADDR_M的值?

代码的工作原理如下:

source.c:

#include "header.h"

union
{
    struct
    {
        unsigned char COMMAND;      //STRUCT_ARRAY[0]
        unsigned char ADDR_H;       //STRUCT_ARRAY[1]
        unsigned char ADDR_M;       //STRUCT_ARRAY[2]
        unsigned char ADDR_L;       //STRUCT_ARRAY[3]
        unsigned char DATA;         //STRUCT_ARRAY[4]
        unsigned char CHECKSUM;     //STRUCT_ARRAY[5]
    };
    unsigned char STRUCT_ARRAY[6];
    //all of the struct members can be accessed from STRUCT_ARRAY by index
}MY_UNION;

void modify(void)
{
    MY_UNION.ADDR_H = somevalue;
    MY_UNION.ADDR_M = somevalue;
    MY_UNION.ADDR_L = somevalue;
}

在main.c中:

#include "header.h"

void main(void)
{
    modify();
    print(MY_UNION.ADDR_H);    //custom function to print values to a screen
    print(MY_UNION.ADDR_M);
    print(MY_UNION.ADDR_L);
}

2 个答案:

答案 0 :(得分:1)

基本程序设计:

  • 永远不要在头文件中声明变量。
  • 切勿对extern使用意大利面编程。
  • 不要在处理协议的翻译单元外部直接暴露此协议结构之类的内部信息。您需要在两者之间有一个抽象层。

快速而肮脏的解决方案:

  • 将h文件中的联合定义更改为typedef:

    typedef union 
    {
        struct
        {
            unsigned char COMMAND;      //STRUCT_ARRAY[0]
            unsigned char ADDR_H;       //STRUCT_ARRAY[1]
            unsigned char ADDR_M;       //STRUCT_ARRAY[2]
            unsigned char ADDR_L;       //STRUCT_ARRAY[3]
            unsigned char DATA;         //STRUCT_ARRAY[4]
            unsigned char CHECKSUM;     //STRUCT_ARRAY[5]
        };
        unsigned char STRUCT_ARRAY[6];
        //all of the struct members can be accessed from STRUCT_ARRAY by index
    } MY_UNION;
    
  • 在.c文件中本地声明实际变量:static MY_UNION my_union;

  • 使用setter / getters访问变量,例如:

    uint8_t get_address_h (void)
    {
      return my_union.ADDR_H;
    }
    
    void set_address_h (uint8_t addr_h)
    {
      my_union.ADDR_H = addr_h;
    }
    

正确的解决方案:

在适当的程序中,您应该完全从其他文件(包括typedef联合)中隐藏该协议的内部内容。

除协议转换器外,其他任何人都不能访问该联合。您将拥有set_addressset_data之类的函数,调用者无需了解协议内部即可知道这些函数。

答案 1 :(得分:-1)

最简单的方法是键入联合的定义

  

在header.h

typedef union
{
    struct
    {
        ...
    };
    unsigned char STRUCT_ARRAY[6];
}MyUnionType;

extern MyUnionType MY_UNION;

然后在source.c中定义变量

MyUnionType MY_UNION;

此变量现在可以在任何源文件中使用。 (main.c等)