1

所以我在 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) ; 但是由于我在开头包含头文件时没有定义它们,所以它可能根本不会包含它们中的任何一个,因此会产生运行时错误。任何对正确方向的建议将不胜感激。提前谢谢各位!

4

2 回答 2

1

我认为这里没有问题。

选项:

  1. 命名以不同方式执行相同操作的 ASM 和 C 函数。使用ifor switchor,上帝保佑,?:调用正确的。
  2. 同名设置如上。使用函数指针。如果你给它分配了 ASM 函数的地址,那么通过这个指针的函数调用就会去那里。如果将 C 函数的地址分配给它,调用将同样转到 C 函数。
  3. 同名设置如上。定义一个可以扩展为 ASM 或 C 函数名称的宏。您可以使用编译器的选项在编译时定义宏。在需要调用这两个函数之一的代码中使用该宏。
  4. 将 ASM 和 C 函数放入单独的 .asm/.s 和 .c 文件中。编译时,要么在已编译文件列表中包含一个文件,要么包含另一个。
于 2012-09-30T06:18:53.637 回答
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.

现在,您将在两个源文件都包含的头文件(即实现该函数的文件和使用它的文件)上像这样使用它:

// 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,您只需将其用作命令行选项,就像这样(例如在密送32):

bcc32 /D"__GSTATE_USE_C_FUNCTION" hello.c

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

于 2012-09-30T06:37:24.423 回答