2012-09-30 37 views
1

所以我在C中做了一些工作,我在汇编和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 

然后在来电者: 包括“headerfile.h” //包括上述头文件 //调用者定义_ Ç _FUNC 定义__C_FUNC callTheRightFunction(m,p,& getstate); 但是由于我在头文件中包含了头文件,当它们都没有被定义时,它可能根本不包含任何头文件,因此会生成运行时错误。 任何建议朝着正确的方向将不胜感激。在此先感谢你们!

+0

使用预处理器指令:像'#ifdef' – mshsayem

+0

不要在全局名称中使用前导下划线。它们保留给编译器和系统实现。如果你想在某一天与C++兼容,不要使用双下划线。 –

回答

1

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

#define __C__FUNC 
#include "header.h" 

但为了避免这个问题,当你不定义任何东西,一种方法是让你只使用一个定义,像这一点,对源文件:

#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。现在

,你会使用这样一个头文件,这两个源文件包括(即,实现了功能的文件,并使用它的文件):

// 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线。另外,如果你的编译器有一个选项可以在命令行中为它做预处理器的定义,那么你甚至不需要在#include之前定义__GSTATE_USE_C_FUNCTION,你只需要用作命令行选项,像这样(例如在bcc32):

bcc32 /D"__GSTATE_USE_C_FUNCTION" hello.c 

这将避免该问题(* 1),而且你不必让这两个源文件必须包括一个全球性的头文件。

1

我看到这里没有问题。

选项:

  1. 名ASM和C函数做同样的不同。使用ifswitch或上帝禁止,?:调用正确的。
  2. 与上面相同的名称设置。使用函数指针。如果您为其分配了ASM功能的地址,那么通过此指针的函数调用将会到达那里。如果您为其分配了C函数的地址,则这些调用将同样转到C函数。
  3. 与上面相同的名称设置。定义一个可扩展为ASM或C函数名称的宏。您可以使用编译器的选项在编译时定义宏。在需要调用其中一个函数的代码中使用该宏。
  4. 将ASM和C函数放入单独的.asm/.s和.c文件中。编译时在编译文件列表中包含一个文件或包含另一个文件。
相关问题