【发布时间】:2019-08-06 17:51:01
【问题描述】:
我正在尝试编写“对象”风格的 C 代码,因为我需要使用不同的参数多次声明同一个对象。除了返回或分配指向已创建对象的指针外,一切正常。我搜索并找到了几个示例,但没有一个有效。
这是有效的。
头文件:
#ifndef _OBJECT_H_
#define _OBJECT_H_
typedef struct
{
uint8_t* Buffer_PU8;
uint8_t Index_U8;
}TParameters_S;
typedef struct
{
uint8_t ID_U8;
TParameters_S* Parameters_PS;
}TObject_S;
#define NEW_OBJECT(id, size) \
static uint8_t Buffer_AU8##id[size]; \
static TParameters_S Parameters_S##id = { \
0, Buffer_AU8##id \
}; \
static const TObject_S __attribute__((used, section("my_objects"))) Object_S##id = { \
id, &Parameters_S##id \
}; \
#endif // _OBJECT_H_
源文件:
#incldue "object.h"
typedef enum
{
OBJECT1_E,
OBJECT2_E,
}TObjects_E;
NEW_OBJECT(OBJECT1_E, 10);
NEW_OBJECT(OBJECT2_E, 20);
void function(void)
{
}
这可以正常工作并在“my_objects”部分中创建两个“对象”。每个对象都有不同大小的缓冲区。
但我想获得一个指向该对象的指针,以便可以对其进行操作。我可以在“my_objects”部分中搜索对象并指向它,但是如果我可以在编译时为该对象分配一个指针,那就太好了。这样我就不必浪费时间或代码空间来搜索对象了。
所以我已经尝试过了,但它不起作用(希望它将一个对象指针分配给“句柄”):
头文件:
#define NEW_OBJECT(id, size, handle) \
static uint8_t Buffer_AU8##id[size]; \
static TParameters_S Parameters_S##id = { \
0, Buffer_AU8##id \
}; \
static const TObject_S __attribute__((used, section("my_objects"))) Object_S##id = { \
id, &Parameters_S##id \
}; \
handle = &Object_S##id; \ <----- This does not work
源文件:
TObject_S* object1_PS;
TObject_S* object1_PS;
// therefore does not work
NEW_OBJECT(OBJECT1_E, 10, object1_PS);
NEW_OBJECT(OBJECT2_E, 20, object2_PS);
void function(void)
{
// Then operate on the object (and therefore this does not work)
object1_PS->Parameters_PS->Buffer_PS[object1_PS->Parameters_PS->Index_U8];
}
我也试过这个,希望它会返回一个指向对象的指针(我想我在这里抓住机会):
头文件:
#define NEW_OBJECT(id, size) \
static uint8_t Buffer_AU8##id[size]; \
static TParameters_S Parameters_S##id = { \
0, Buffer_AU8##id \
}; \
static const TObject_S __attribute__((used, section("my_objects"))) Object_S##id = { \
id, &Parameters_S##id \
}; \
&Object_S##id; \ <----- This does not work
源文件:
// therefore this does not work
TObject_S* object1_PS = NEW_OBJECT(OBJECT1_E, 10, object1_PS);
TObject_S* object1_PS = NEW_OBJECT(OBJECT2_E, 20, object2_PS);
void function(void)
{
// Then operate on the object (and therefore this does not work)
object1_PS->Parameters_PS->Buffer_PS[object1_PS->Parameters_PS->Index_U8];
}
这可行,但我认为它为每个对象创建了两个指针。虽然我只能在地图文件中看到每个对象的一个指针:
头文件:
#define NEW_OBJECT(id, size, handle) \
static uint8_t Buffer_AU8##id[size]; \
static TParameters_S Parameters_S##id = { \
0, Buffer_AU8##id \
}; \
static const TObject_S __attribute__((used, section("my_objects"))) Object_S##id = { \
id, &Parameters_S##id \
}; \
static const TObject_S* __attribute__((used, section("my_objects_pointers"))) handle = &Object_S##id; \ <----- This works
源文件:
TObject_S* object1_PS;
TObject_S* object1_PS;
// therefore this works
NEW_OBJECT(OBJECT1_E, 10, object1_PS);
NEW_OBJECT(OBJECT2_E, 20, object2_PS);
void function(void)
{
// Then operate on the object (and therefore this works)
object1_PS->Parameters_PS->Buffer_PS[object1_PS->Parameters_PS->Index_U8];
}
【问题讨论】:
-
"如果我可以在编译时为对象分配一个指针,那就太好了" - 我认为您真的不想这样做。您对环境的内存管理有这种类型的控制吗?
-
为什么不呢?每次我调用 NEW_OBJECT 时,编译器都会创建 struct TObject 的单个实例,并且链接器会将它放在“my_objects”部分中。现在我只想要一个指向该对象的变量。它就像指向结构的任何其他变量一样。没有错。
-
请注意,
#define _OBJECT_H_是非法的。以下划线和大写字母开头的标识符在所有上下文中都是保留的。 -
为什么不直接使用
&Object_SOBJECT1_E作为指向对象的指针呢? -
"编译器将创建结构的单个实例" -- 不,它不会。