C 编程 - 全局可见的实例

C programming - globally seen instance

我想声明一个可以在所有源文件中访问的结构实例。更准确地说,我有一个代表环形缓冲区的结构。我的程序的两个部分可以写入缓冲区,因此我需要以某种方式在我的源文件之间共享相同的缓冲区实例。这是我的想法,但行不通:

在 buf.h 文件中将缓冲区的实例声明为 extern,并创建函数 ringBuf_get(),它将 return 指向我的缓冲区实例的指针。

extern ringBuf buf_frames;
ringBuf *ringBuf_get(void);

所以我会在 buf.c 中这样实现 ringBuf_get():

ringBuf *ringBuf_get(void)
{
    return &buf_frames;
}

然后每当我想对缓冲区进行一些操作时,我会先调用ringBuf_get来获取缓冲区的实例,然后再进行操作。但似乎我做错了什么。请随时发表评论。

bool ringBuf_write(ringBuf *_this, uint8_t *mac_protocol_data_unit, uint8_t length)
{
    if(_this->write->alloc == false)
    {
        _this->write->alloc = true;
        _this->write->len = length;
        memcpy(_this->write->data, mac_protocol_data_unit, length);
        if(_this->write == &_this->buf_pool[MAX_BUF_POOL_SIZE])
            _this->write = &_this->buf_pool[0];
        else
            _this->write++;
        xil_printf("\n\n Write Suceeded! \n\n");
        return true;
    }
    else
    {
        if (ringBuf_full(_this))
        {
           xil_printf("\n\n BUFFER IS FULL! \n\n");
        }
        return false;
    }
}

您没有向我们展示太多代码,但是这个语句(或其他语句!)会破坏数组吗?

if(_this->write == &_this->buf_pool[MAX_BUF_POOL_SIZE])

通常,当您定义数组的 SIZE 时,它可以在 0..(SIZE-1) 范围内进行索引。我提出这个建议是因为你的一个问题是在只有 4 个缓冲区时能够写入第 5 个缓冲区。

header不需要声明

extern ringBuf buf_frames;

函数就足够了——最好只公开函数而不公开全局变量。实际上,该变量应该在定义它的文件中设为static(并且必须有这样一个文件;大概是buf.c)。使变量static意味着其他文件无法通过名称访问它,但他们可以调用函数获取指向变量的指针然后访问它。

辅助问答

It seems that every time I write:

ringBuf_write(ringBuf_get(), packet1, 127);
ringBuf_write(ringBuf_get(), packet2, 64);
ringBuf_write(ringBuf_get(), packet1, 127);

I get a new instance by calling ringBuf_get(). So instead of movingthe pointer and writing to another frame in the buffer, I write to the same frame. Also the buffer does not remember that I have already allocated, for example, frame 0.

然后您需要检查您的问题并解释问题所在,最好使用 MCVE (How to create a Minimal, Complete, and Verifiable Example?) or SSCCE (Short, Self-Contained, Correct Example) — 两个名称和链接用于相同的基本思想。

您每次都将 ringBuf_get() 函数写入 return 指向相同数据结构的指针。这可能是正确的,但你所说的 'I get new instance by calling ringBuf_get()' 的意思还不清楚。您每次都会得到相同的实例。如果您没有正确更新该实例,或者您需要每次都指向不同的实例,则需要修复代码。

不清楚您在哪里检查要复制到 _this->write->data 的内存是否足够小。

此外,不清楚_this->buf_pool数组有多大。如果不是大小MAX_BUF_POOL_SIZE+1,你在代码中写越界有问题:

    if(_this->write == &_this->buf_pool[MAX_BUF_POOL_SIZE])
        _this->write = &_this->buf_pool[0];
    else
        _this->write++;

可以说伤害是在那之前的memcpy()造成的。在不分配内存的情况下设置 _this->alloc = true; 的代码也令人担忧。我不能说它是否是错误的;您没有显示足够的代码或结构的详细定义。

您如何对环形缓冲区代码进行单元测试?告诉您缓冲区被正确处理的所有诊断打印语句在哪里?如果您不能或拒绝添加打印代码,您是否 运行 调试器中的函数?环形缓冲区的设计到底是什么?