如何在C中执行条件函数调用?

时间:2012-09-30 06:10:40

标签: c function-pointers conditional-compilation

所以我在C中做了一些工作,我在程序集和C中都实现了相同的功能,我想比较C与程序集实现的性能。为此,我希望能够有条件地编译和调用函数,即我想创建一个函数,它将充当调用者和我想要调用的正确函数之间的接口。不知怎的,我不知道该怎么做。 我正在思考以下几点:

//header file containing the C definition and the assembly definition

void getstate(state* m, int* values);   
extern void kalmanstate(state* m, int* values);

然后调用者可以包含上面的头文件并传递& getstate或& kalmanstate。

void callTheRightFunction(state* m, int* values, void *fnptr(state*,int*))
{
  *fnptr(m,values);
}

然而,问题是getstate和kalmanstate都会被编译,这会破坏我模拟的目的。对我来说听起来不是我想要的包装器的最佳实现。我知道C中存在条件执行,但我如何使用它来获得正确的函数编译?我的意思是如果我在头文件中做这样的事情:

#ifdef __C__FUNC
void getstate(state* m, int *values);
#endif
#ifdef __kalman
void kalmanstate(state *m, int *values)
#endif

然后在来电者中:     include" headerfile.h" //包含上面的头文件     //调用者定义_ C _FUNC     定义__C_FUNC     callTheRightFunction(M,P,&安培;有getstate); 但是由于我在开头时没有定义头文件,因此可能根本不包含任何头文件,因此会生成运行时错误。 任何有关正确方向的建议都将受到赞赏。先谢谢你们!

2 个答案:

答案 0 :(得分:1)

我认为这里没问题。

选项:

  1. 将执行相同操作的ASM和C函数命名为。使用ifswitch或上帝保佑,?:拨打正确的电话。
  2. 与上面相同的名称设置。使用函数指针。如果为它分配ASM函数的地址,则通过该指针的函数调用将在那里进行。如果为其分配C函数的地址,则调用将类似地转到C函数。
  3. 与上面相同的名称设置。定义一个可以扩展为ASM或C函数名称的宏。您可以使用编译器的选项在编译时定义宏。在需要调用两个函数之一的代码中使用该宏。
  4. 将ASM和C函数放入单独的.asm / .s和.c文件中。编译时,在编译文件列表中包含一个文件或包含另一个文件。

答案 1 :(得分:1)

根据您对原始问题的补充,您想知道是否没有编译任何函数。然后,在包含头文件之前,您必须定义__C__FUNC__kalman

#define __C__FUNC
#include "header.h"

但是为了避免在没有定义任何内容时出现这个问题,一种方法是在SOURCE文件中只使用一个这样的定义:

#ifdef __GSTATE_USE_C_FUNCTION
void getstate(state* m, int *values)
{
    // C version
}
#else
void getstate(state *m, int *values)
{
    // Assembly version
}
#endif

在头文件中:

void getstate(state *m, int *values);

(注意相同的函数名,因此在调用函数时不需要修改代码)

但是,只有当您在源文件中包含标题getstate时,这才会起作用。的(* 1)

然后,如果您在包含标题之前忘记定义__GSTATE_USE_C_FUNCTION,则会使用第二个函数,因为它会触发#else

现在,您可以在BOTH源文件包含的头文件(即实现该函数的文件和使用它的文件)中使用它:

// Comment the line below if you want the other version
#define __GSTATE_USE_C_FUNCTION

当然,在包含包含原型声明的标题之前,您必须包含此标题。

在源文件上:

// Somewhere else on the code where you use the function
getstate(m, values);

因此,您只需更改全局标题上的#define行。

此外,如果你的编译器有一个选项可以在命令行中为它定义预处理器,那么你甚至不需要在__GSTATE_USE_C_FUNCTION之前定义#include,你只需要使用它作为命令行选项,像这样(例如在bcc32中):

bcc32 /D"__GSTATE_USE_C_FUNCTION" hello.c

这可以避免问题(* 1),并且您不必创建两个源文件都必须包含的全局头文件。