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;
的代码也令人担忧。我不能说它是否是错误的;您没有显示足够的代码或结构的详细定义。
您如何对环形缓冲区代码进行单元测试?告诉您缓冲区被正确处理的所有诊断打印语句在哪里?如果您不能或拒绝添加打印代码,您是否 运行 调试器中的函数?环形缓冲区的设计到底是什么?
我想声明一个可以在所有源文件中访问的结构实例。更准确地说,我有一个代表环形缓冲区的结构。我的程序的两个部分可以写入缓冲区,因此我需要以某种方式在我的源文件之间共享相同的缓冲区实例。这是我的想法,但行不通:
在 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;
的代码也令人担忧。我不能说它是否是错误的;您没有显示足够的代码或结构的详细定义。
您如何对环形缓冲区代码进行单元测试?告诉您缓冲区被正确处理的所有诊断打印语句在哪里?如果您不能或拒绝添加打印代码,您是否 运行 调试器中的函数?环形缓冲区的设计到底是什么?