繁体   English   中英

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;
}

dynamicStringVTableleDynamicStringVTable类型的静态常量。

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中的两个指针。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM