簡體   English   中英

C中工會成員的條件替換

[英]Conditional substitution of union member in C

我有

typedef union 
{
    void (*fp1p)(void);
    void (*fp2p)(uint32_t);
    void (*fp3p)(uint32_t, uint32_t);
    void (*fp4p)(uint32_t, uint32_t, uint32_t);
    uint32_t (*fp5p)(uint32_t);
    uint32_t (*fp6p)(uint32_t, uint32_t);
    uint32_t (*fp7p)(uint32_t, uint32_t, uint32_t);
} fp;
struct command
{
    char *name;  //command name
    uint32_t minargs;
    uint32_t maxargs;
    int minval;
    int maxval;
    fp read_func_pointer;
    fp write_func_pointer;
};

struct command commands[] = 
{
    [0] = { "reg1001", 0,0,0,0, .read_func_pointer.fp6p = TDC1000_SPIByteReadReg, .write_func_pointer.fp4p = TDC1000_SPIByteWriteReg },
    //
   //
   };

接着

if(condition)
{
   uint32_t ret_val = commands[0].read_func_pointer.fp6p(…);
}
else
{
   commands[0]. write_func_pointer.fp6p(…);
}

如何使其通用而不是.fp6p?

我不知道這是否是您的選擇,但是如何將代表函數指針類型的枚舉添加到您的結構中呢?

在conditon語句中,您可以打開枚舉,然后調用正確的函數指針。

我認為您可以為工會使用匿名成員:

struct command
{
    char *name;  //command name
    ...
    union 
    {
        ....
        void (*fp4p)(uint32_t, uint32_t, uint32_t);
        uint32_t (*fp6p)(uint32_t, uint32_t);
    };
    ...
};

對於write_func成員,必須將fp6p等名稱fp6pw為fp6pw。 然后直接調用commands[0].fp6p(...) 不確定,但初始化必須是您想要的“泛型”。

我想澄清一下。 假設我們有幾個命令

struct command commands[] = {
 [0] = { "reg1001", 0,0,0,0, .read_func_pointer.fp6p =      TDC1000_SPIByteReadReg, .write_func_pointer.fp4p = TDC1000_SPIByteWriteReg },
   [1] = = { "reg7201", 0,0,0,0, .read_func_pointer.fp3p =   TDC7200_SPIByteReadReg, .write_func_pointer.fp5p = TDC7200_SPIByteWriteReg },
};

我有一個通用功能來選擇傳入命令

For (i=0; I < sizeof(commands); i++)
{
    if (strcmp(commands[i].name,args[0])==0)
    {
        commands[i]. read_func_pointer.<- Here – how can I know what    pointer to place?
    }
 }

在便攜式標准C99或C11中,無法實現僅在運行時調用簽名功能。 簽名應該在編譯時就已經知道(您可以擴展代碼,從概念上講,可以通過帶有標記的函數指針聯合 ,即保留用於描述簽名的標簽)。 之所以這樣,是因為調用約定可以(並且確實)隨函數簽名而變化(ABI將使用不同的寄存器來傳遞不同種類或類型的參數或結果)。

或者,考慮使用libffi 它包含了一些魔法(匯編代碼,依賴於的ABI ),這將調用一個任意函數指針其簽名是由一些元數據描述

如果您以POSIX為目標,則可以使用一些dlopendlsym技巧(您可能還考慮在Qt5POCOGlib等框架中支持插件)。 您可能會(在運行時)在generated-code-001.cgenerated-code-001.c一些適當的(膠水)C代碼,通過派生一些編譯器命令進行編譯(例如, gcc -Wall -O -fPIC generated-code-001.c -shared -o generated-code-001.so ),然后dlopen ./generated-code-001.so共享對象(在Linux上;在MacOSX上,編譯命令和文件擴展名不同),然后使用dlsym獲取函數指針。 我在MELT中廣泛使用了這些技巧

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM