c - 没有 malloc AVR 的共享指针

标签 c pointers embedded avr

标题可能不太清楚,我举个例子。

我正在尝试用 C 语言创建一个“数据流”系统。

输入STREAM:

typedef struct {
    void (*tx) (uint8_t b);
    uint8_t (*rx) (void);
} STREAM;

我有一个带有 uart.c 的文件 uart.h,它应该为 UART 提供 STREAM

我决定最好将其公开为指针,这样就可以将其传递给函数而不使用&符号。

这是我想使用它的功能(示例):

/** Send signed int */
void put_i16(const STREAM *p, const int16_t num);

这是我的 UART 文件:

uart.h

extern STREAM* uart;

uart.c

// Shared stream instance
static STREAM _uart_singleton;
STREAM* uart;

void uart_init(uint16_t ubrr) {
    // uart init code here

    // Create the stream
    _uart_singleton.tx = &uart_tx; // function pointers
    _uart_singleton.rx = &uart_rx;

    uart = &_uart_singleton; // expose a pointer to it
}

我对此不太确定。它有效,但这是正确的方法吗?我应该只使用 Malloc 吗?

为什么我问这个,它是一个库代码,我希望它尽可能干净和“正确”

最佳答案

全局指针是不必要的( as are all globals ),并且不安全 - 它是非常量;任何有权访问该指针的代码都可以修改_uart_singleton

uart.h

const STREAM* getUart() ;
...

uart.c

// Shared stream instance
static STREAM _uart_singleton = {0} ;

const STREAM* getUart()
{
    // Return singleton if initialised, 
    // otherwise NULL
    return _uart_singleton.rx != 0 && 
           _uart_singleton.tx != 0 ? _uart_singleton :
                                     NULL ;
}

void uart_init(uint16_t ubrr) 
{
    // uart init code here

    // Create the stream
    _uart_singleton.tx = &uart_tx; // function pointers
    _uart_singleton.rx = &uart_rx;
}

只要访问 STREAM 成员的所有函数都是在 uart.c 中定义的,那么您也可以从使 STREAM 成为不透明类型中受益(Lundin 在评论中的建议)通过在 header 中使用不完整的结构声明:

uart.h

struct sStream ;
typedef struct sStream STREAM ;

const STREAM* getUart() ;
...

uart.c

// Shared stream instance
struct sStream 
{
    void (*tx) (uint8_t b);
    uint8_t (*rx) (void);

} _uart_singleton = {0} ;

const STREAM* getUart()
{
    // Return singleton if initialised, 
    // otherwise NULL
    return _uart_singleton.rx != 0 && 
           _uart_singleton.tx != 0 ? _uart_singleton :
                                     NULL ;
}

...

这可以防止 uart.c 之外的任何代码直接调用 rxtx 函数或访问任何其他成员。

关于c - 没有 malloc AVR 的共享指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29967303/

相关文章:

c - 如何声明 printf()?

c - 返回指向数组的指针的函数中的段错误

c - 在 pic 18F4550 上启用端口 RB4 和 RB3

c - ANSI C 中的超便携、小型复杂配置文件库?

c - 尝试使用 mingw 构建和编译 lua 5.3.3 , undefined reference 错误

c - 为什么 'z'中存储的值为35?难道不应该是20吗,因为在函数 'c=*b'中(c等于*b指向的值)?

c++ - 在 C++ 中使用指针

c++ - 为什么我必须将地址转换为整数才能使其可分配?

c++ - 没有全局运营商的裸机新

c - UNIX 风格的套接字编程技巧