Microchip 图形库中的 C 宏定义:它是如何工作的?
C Macro definition in Microchip Graphics Library: How does it work?
这是 Microchip Legato 图形库中的定义。
我不明白那是做什么的。也许这里有人知道这是要做什么?
虽然我写了很多 C 语言,但我没有遇到过这种类型的东西,我正在努力移植旧代码以适应这个库。
这里是头文件中宏和相关结构的定义
typedef struct leDynamicString
{
leString base; /**< base data */
const leDynamicStringVTable* fn; /**< function table */
leChar* data; /**< data storage */
uint16_t capacity; /**< string capacity */
uint16_t length; /**< string length */
const leFont* font; /**< string font */
} leDynamicString;
#define LE_STRING_VTABLE(THIS_TYPE) \
void (*destructor)(THIS_TYPE* _this); \
leFont* (*getFont)(const THIS_TYPE* _this); \
leResult (*setFont)(THIS_TYPE* _this, const leFont* font); \
leResult (*setFromString)(THIS_TYPE* _this, const struct leString* src); \
leResult (*setFromChar)(THIS_TYPE* _this, const leChar* buf, uint32_t size); \
leResult (*setFromCStr)(THIS_TYPE* _this, const char* cstr); \
leChar (*charAt)(const THIS_TYPE* _this, uint32_t idx); \
uint32_t (*length)(const THIS_TYPE* _this); \
leBool (*isEmpty)(const THIS_TYPE* _this); \
int32_t (*compare)(const THIS_TYPE* _this, const struct leString* tgt); \
leResult (*append)(THIS_TYPE* _this, const struct leString* val); \
leResult (*insert)(THIS_TYPE* _this, const struct leString* val, uint32_t idx); \
leResult (*remove)(THIS_TYPE* _this, uint32_t idx, uint32_t count); \
void (*clear)(THIS_TYPE* _this); \
uint32_t (*toChar)(const THIS_TYPE* _this, leChar* buf, uint32_t size); \
leResult (*getRect)(const THIS_TYPE* _this, leRect* rect); \
uint32_t (*getLineCount)(const THIS_TYPE* _this); \
leResult (*getLineRect)(const THIS_TYPE* _this, uint32_t line, leRect* rect); \
leResult (*getLineIndices)(const THIS_TYPE* _this, uint32_t line, uint32_t* start, uint32_t* end); \
leResult (*getCharRect)(const THIS_TYPE* _this, uint32_t idx, leRect* rect); \
leResult (*getCharIndexAtPoint)(const THIS_TYPE* _this, const lePoint* pt, uint32_t* idx); \
leResult (*_draw)(const THIS_TYPE* _this, int32_t x, int32_t y, leHAlignment align, leColor clr, uint32_t a); \
void (*preinvalidate)(THIS_TYPE* _this); \
void (*invalidate)(THIS_TYPE* _this); \
leResult (*setPreInvalidateCallback)(THIS_TYPE* _this, leString_InvalidateCallback, void* userData); \
leResult (*setInvalidateCallback)(THIS_TYPE* _this, leString_InvalidateCallback, void* userData); \
typedef struct leStringVTable
{
LE_STRING_VTABLE(struct leString)
} leStringVTable;
static const leDynamicStringVTable dynamicStringVTable =
{
// base class funcs
.invalidate = (void*)_leString_Invalidate,
.setPreInvalidateCallback = (void*)_leString_SetPreInvalidateCallback,
.setInvalidateCallback = (void*)_leString_SetInvalidateCallback,
// member funcs
.destructor = _leDynamicString_Destructor,
.setFromString = _leDynamicString_SetFromString,
.setFromChar = _leDynamicString_SetFromChar,
.setFromCStr = _leDynamicString_SetFromCStr,
.charAt = _leDynamicString_CharAt,
.length = _leDynamicString_Length,
.isEmpty = _leDynamicString_IsEmpty,
.compare = _leDynamicString_Compare,
.append = _leDynamicString_Append,
.insert = _leDynamicString_Insert,
.remove = _leDynamicString_Remove,
.clear = _leDynamicString_Clear,
.toChar = _leDynamicString_ToChar,
.getCapacity = _leDynamicString_GetCapacity,
.setCapacity = _leDynamicString_SetCapacity,
};
struct leDynamicString;
static const leDynamicStringVTable dynamicStringVTable;
/******************************And here is the MACRO ****/
#define LE_DYNAMICSTRING_VTABLE(THIS_TYPE) \
LE_STRING_VTABLE(THIS_TYPE) \
\
uint32_t (*getCapacity)(THIS_TYPE* str); \
leResult (*setCapacity)(THIS_TYPE* str, uint32_t cap); \
typedef struct leDynamicStringVTable
{
LE_DYNAMICSTRING_VTABLE(struct leDynamicString)
} leDynamicStringVTable;
并且在这个函数中用到了:
编辑:不是直接的,而是变量 dynamicStringVTable 分解成那个宏
static const leDynamicStringVTable dynamicStringVTable;
void leDynamicString_Constructor(leDynamicString* _this)
{
_this->base.fn = (void*)&dynamicStringVTable; //Here
_this->fn = (void*)&dynamicStringVTable;
}
dynamicStringVTable
是 leDynamicStringVTable
.
类型的静态常量
leDynamicStringVTable
是一个结构。因为它在定义中使用了几个嵌套的宏,所以一步一步解开它需要一些时间,但仅此而已。
所以:
typedef struct leDynamicStringVTable
{
LE_DYNAMICSTRING_VTABLE(struct leDynamicString)
} leDynamicStringVTable;
扩展为:
typedef struct leDynamicStringVTable
{
LE_STRING_VTABLE(struct leDynamicString)
uint32_t (*getCapacity)(struct leDynamicString* str);
leResult (*setCapacity)(struct leDynamicString* str, uint32_t cap);
} leDynamicStringVTable;
这扩展为:
typedef struct leDynamicStringVTable
{
void (*destructor)(struct leDynamicString* _this);
leFont* (*getFont)(const struct leDynamicString* _this);
leResult (*setFont)(struct leDynamicString* _this, const leFont* font);
/* ... a bunch of other function pointers ... */
void (*preinvalidate)(struct leDynamicString* _this);
void (*invalidate)(struct leDynamicString* _this);
leResult (*setPreInvalidateCallback)(struct leDynamicString* _this, leString_InvalidateCallback, void* userData);
leResult (*setInvalidateCallback)(struct leDynamicString* _this, leString_InvalidateCallback, void* userData);
uint32_t (*getCapacity)(struct leDynamicString* str);
leResult (*setCapacity)(struct leDynamicString* str, uint32_t cap);
} leDynamicStringVTable;
静态常量dynamicStringVTable
用一些函数初始化:
static const leDynamicStringVTable dynamicStringVTable =
{
// base class funcs
.invalidate = (void*)_leString_Invalidate,
.setPreInvalidateCallback = (void*)_leString_SetPreInvalidateCallback,
.setInvalidateCallback = (void*)_leString_SetInvalidateCallback,
// member funcs
.destructor = _leDynamicString_Destructor,
/* ... */
};
并且指向这个实例的指针用于在构造函数中初始化两个指针leDynamicString_Constructor
。
这是 Microchip Legato 图形库中的定义。 我不明白那是做什么的。也许这里有人知道这是要做什么?
虽然我写了很多 C 语言,但我没有遇到过这种类型的东西,我正在努力移植旧代码以适应这个库。
这里是头文件中宏和相关结构的定义
typedef struct leDynamicString
{
leString base; /**< base data */
const leDynamicStringVTable* fn; /**< function table */
leChar* data; /**< data storage */
uint16_t capacity; /**< string capacity */
uint16_t length; /**< string length */
const leFont* font; /**< string font */
} leDynamicString;
#define LE_STRING_VTABLE(THIS_TYPE) \
void (*destructor)(THIS_TYPE* _this); \
leFont* (*getFont)(const THIS_TYPE* _this); \
leResult (*setFont)(THIS_TYPE* _this, const leFont* font); \
leResult (*setFromString)(THIS_TYPE* _this, const struct leString* src); \
leResult (*setFromChar)(THIS_TYPE* _this, const leChar* buf, uint32_t size); \
leResult (*setFromCStr)(THIS_TYPE* _this, const char* cstr); \
leChar (*charAt)(const THIS_TYPE* _this, uint32_t idx); \
uint32_t (*length)(const THIS_TYPE* _this); \
leBool (*isEmpty)(const THIS_TYPE* _this); \
int32_t (*compare)(const THIS_TYPE* _this, const struct leString* tgt); \
leResult (*append)(THIS_TYPE* _this, const struct leString* val); \
leResult (*insert)(THIS_TYPE* _this, const struct leString* val, uint32_t idx); \
leResult (*remove)(THIS_TYPE* _this, uint32_t idx, uint32_t count); \
void (*clear)(THIS_TYPE* _this); \
uint32_t (*toChar)(const THIS_TYPE* _this, leChar* buf, uint32_t size); \
leResult (*getRect)(const THIS_TYPE* _this, leRect* rect); \
uint32_t (*getLineCount)(const THIS_TYPE* _this); \
leResult (*getLineRect)(const THIS_TYPE* _this, uint32_t line, leRect* rect); \
leResult (*getLineIndices)(const THIS_TYPE* _this, uint32_t line, uint32_t* start, uint32_t* end); \
leResult (*getCharRect)(const THIS_TYPE* _this, uint32_t idx, leRect* rect); \
leResult (*getCharIndexAtPoint)(const THIS_TYPE* _this, const lePoint* pt, uint32_t* idx); \
leResult (*_draw)(const THIS_TYPE* _this, int32_t x, int32_t y, leHAlignment align, leColor clr, uint32_t a); \
void (*preinvalidate)(THIS_TYPE* _this); \
void (*invalidate)(THIS_TYPE* _this); \
leResult (*setPreInvalidateCallback)(THIS_TYPE* _this, leString_InvalidateCallback, void* userData); \
leResult (*setInvalidateCallback)(THIS_TYPE* _this, leString_InvalidateCallback, void* userData); \
typedef struct leStringVTable
{
LE_STRING_VTABLE(struct leString)
} leStringVTable;
static const leDynamicStringVTable dynamicStringVTable =
{
// base class funcs
.invalidate = (void*)_leString_Invalidate,
.setPreInvalidateCallback = (void*)_leString_SetPreInvalidateCallback,
.setInvalidateCallback = (void*)_leString_SetInvalidateCallback,
// member funcs
.destructor = _leDynamicString_Destructor,
.setFromString = _leDynamicString_SetFromString,
.setFromChar = _leDynamicString_SetFromChar,
.setFromCStr = _leDynamicString_SetFromCStr,
.charAt = _leDynamicString_CharAt,
.length = _leDynamicString_Length,
.isEmpty = _leDynamicString_IsEmpty,
.compare = _leDynamicString_Compare,
.append = _leDynamicString_Append,
.insert = _leDynamicString_Insert,
.remove = _leDynamicString_Remove,
.clear = _leDynamicString_Clear,
.toChar = _leDynamicString_ToChar,
.getCapacity = _leDynamicString_GetCapacity,
.setCapacity = _leDynamicString_SetCapacity,
};
struct leDynamicString;
static const leDynamicStringVTable dynamicStringVTable;
/******************************And here is the MACRO ****/
#define LE_DYNAMICSTRING_VTABLE(THIS_TYPE) \
LE_STRING_VTABLE(THIS_TYPE) \
\
uint32_t (*getCapacity)(THIS_TYPE* str); \
leResult (*setCapacity)(THIS_TYPE* str, uint32_t cap); \
typedef struct leDynamicStringVTable
{
LE_DYNAMICSTRING_VTABLE(struct leDynamicString)
} leDynamicStringVTable;
并且在这个函数中用到了: 编辑:不是直接的,而是变量 dynamicStringVTable 分解成那个宏
static const leDynamicStringVTable dynamicStringVTable;
void leDynamicString_Constructor(leDynamicString* _this)
{
_this->base.fn = (void*)&dynamicStringVTable; //Here
_this->fn = (void*)&dynamicStringVTable;
}
dynamicStringVTable
是 leDynamicStringVTable
.
leDynamicStringVTable
是一个结构。因为它在定义中使用了几个嵌套的宏,所以一步一步解开它需要一些时间,但仅此而已。
所以:
typedef struct leDynamicStringVTable
{
LE_DYNAMICSTRING_VTABLE(struct leDynamicString)
} leDynamicStringVTable;
扩展为:
typedef struct leDynamicStringVTable
{
LE_STRING_VTABLE(struct leDynamicString)
uint32_t (*getCapacity)(struct leDynamicString* str);
leResult (*setCapacity)(struct leDynamicString* str, uint32_t cap);
} leDynamicStringVTable;
这扩展为:
typedef struct leDynamicStringVTable
{
void (*destructor)(struct leDynamicString* _this);
leFont* (*getFont)(const struct leDynamicString* _this);
leResult (*setFont)(struct leDynamicString* _this, const leFont* font);
/* ... a bunch of other function pointers ... */
void (*preinvalidate)(struct leDynamicString* _this);
void (*invalidate)(struct leDynamicString* _this);
leResult (*setPreInvalidateCallback)(struct leDynamicString* _this, leString_InvalidateCallback, void* userData);
leResult (*setInvalidateCallback)(struct leDynamicString* _this, leString_InvalidateCallback, void* userData);
uint32_t (*getCapacity)(struct leDynamicString* str);
leResult (*setCapacity)(struct leDynamicString* str, uint32_t cap);
} leDynamicStringVTable;
静态常量dynamicStringVTable
用一些函数初始化:
static const leDynamicStringVTable dynamicStringVTable =
{
// base class funcs
.invalidate = (void*)_leString_Invalidate,
.setPreInvalidateCallback = (void*)_leString_SetPreInvalidateCallback,
.setInvalidateCallback = (void*)_leString_SetInvalidateCallback,
// member funcs
.destructor = _leDynamicString_Destructor,
/* ... */
};
并且指向这个实例的指针用于在构造函数中初始化两个指针leDynamicString_Constructor
。