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

Can I access a union in my source.c from main.c in PIC C18?

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

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 ,这两个文件都包含,我们称之为 header.h.

我如何读取 main.c 中 ADDR_HADDR_M 的值,同时从 source.c 定期修改它?

代码有点像这样:

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);
}

最简单的方法是对联合进行类型定义

in header.h

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

extern MyUnionType MY_UNION;

然后在source.c定义变量

MyUnionType MY_UNION;

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

基础程序设计:

  • 切勿在头文件中声明变量。
  • 切勿使用 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 等函数,调用者可以在不知道协议内部结构的情况下知道这些函数。