0

我有一个项目,还有一个案例,我有一些经常更改#define的预处理器来控制它的工作方式——例如:

void myfunction(int num, mystruct* content) {
    doSomethingTo(content);
    //...
    #ifdef FEATURE_X
    feature_x(content);
    #endif
}

这很好用,虽然每次都必须重新编译,所以它在“每次都必须重新编译的东西”文件中。我想将其推送到 [静态] 库中。我可以更改它的调用方式(已经有一个用于 pick 的函数指针myFunction),所以我希望它变成

void myfunction(int num, mystruct* content) {
    doSomethingTo(content);
    //...
}
void myfunction_featureX(int num, mystruct* content) {
    doSomethingTo(content);
    //...
    feature_x(content);
}

我需要在几个地方执行此操作,因此-D FEATURE_X为每个地方使用一个单独的库(一个有一个没有 )不是一个可接受的选择。我可以通过复制/粘贴来做到这一点,但这会导致代码重用,这会带来修复一个副本而不是另一个副本的错误的风险。

4

3 回答 3

1

如果您将 myfeature_x 放在函数表中会有所帮助吗?

#include <stdio.h>
#include <string.h>

typedef struct {
  int x,y;
} mystruct;

typedef void (*fn_ptr)(mystruct* content);
fn_ptr vtable[10];
#define FEATURE_X_INDEX 0

void feature_x(mystruct *content)
{
  printf("y: %d\n", content->y);
}

void myfunction(int num, mystruct* content) {
  printf("x: %d\n", content->x);

  //...
  if (vtable[FEATURE_X_INDEX]) {
    vtable[FEATURE_X_INDEX](content);
  }
}

int main(void)
{
  bzero(vtable, sizeof(vtable));
  mystruct s;
  s.x = 1;
  s.y = 2;
  myfunction(0, &s);
  if (1) {
    //Of course you'd use a more sensible condition.
    vtable[FEATURE_X_INDEX] = feature_x;
  }
  myfunction(0, &s);
  return 0;
}

输出:

x: 1
x: 1
y: 2

然后,您需要做的就是在NULL不使用该功能时用 s 填充虚函数表,如果要使用它,则用函数指针填充。您可以从任何地方执行此操作 - 例如静态库.. 或者您可以编译feature_x成动态库,在运行时加载它,如果加载成功填充函数表,并在卸载动态链接库时清除表.

我认为与 Jonathan Leffler 的方法相比,这真正给您带来的唯一好处是 feature_x 的代码实际上不需要与您的其他代码链接到相同的二进制文件中。如果您只需要一个运行时开关来打开或关闭该功能if,那么正如 Jonathan Leffler 所建议的那样,一个简单的语句应该可以解决问题。(顺便说一下,if这里也有一个 - 它检查函数表的内容:))

于 2013-02-02T23:49:13.193 回答
1

让 featureX 版本的函数调用主线函数。在您的示例myfunction_featureX中会调用myfunction然后做自己的事情。

于 2013-02-02T23:42:26.880 回答
1

当然,这就是您将 Feature X 的激活从编译时问题更改为运行时问题的地方:

void myfunction(int num, mystruct* content)
{
    doSomethingTo(content);
    //...
    if (FeatureX_Enabled())
        feature_x(content);
}

测试可能是一个完整的FeatureX_Enabled()函数,也可能只是测试一个在函数外部定义的适当范围的变量——文件中的静态变量或外部变量。这避免了必须使用函数指针;它与现在调用的函数相同。更改函数指针表相当于更改单个变量 - 它涉及更改存储在函数外部的某些内容的值以更改函数的行为。

于 2013-02-03T00:02:50.433 回答