在C中有条件地替换工会成员

时间:2015-05-27 06:46:47

标签: 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?

4 个答案:

答案 0 :(得分:0)

我不知道这是否适合您,但是如何在结构中添加表示函数指针类型的枚举?

在conditon语句中,您可以打开枚举,然后调用右侧的函数指针。

答案 1 :(得分:0)

我认为您可以使用匿名成员加入工会:

//This will filter the product list based on all 3 criteria
<div class="product" data-ng-repeat="product in products | filter:{rating:selectedRating, id:selectedId,productName:selectedProduct }"></div>

对于write_func成员,您必须将struct command { char *name; //command name ... union { .... void (*fp4p)(uint32_t, uint32_t, uint32_t); uint32_t (*fp6p)(uint32_t, uint32_t); }; ... }; 等名称更改为fp6p。然后直接致电fp6pw。不确定但初始化必须是&#34;泛型&#34;如你所愿。

答案 2 :(得分:0)

我想澄清一下。 假设我们有几个命令

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

答案 3 :(得分:0)

在便携式标准C99或C11中无法调用仅在运行时已知的签名功能;签名应该在编译时知道(并且您可以通过使用tagged union函数指针来扩展代码,即通过保留描述签名的标记来扩展代码。这是因为calling conventions可以(并且确实)随函数签名而变化(ABI将使用不同的寄存器来传递不同种类或类型的参数或结果)。

或者,考虑使用libffi;它包含一些魔法(汇编代码,依赖于ABI),它调用任意函数指针,其签名由某些元数据描述

如果你的目标是POSIX,你可以使用一些dlopen&amp; dlsym技巧(您也可以考虑Qt5POCOGlib等框架中的插件支持。您可以在generated-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

中广泛使用这些技巧