2012-09-30 38 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文件中。編譯時在編譯文件列表中包含一個文件或包含另一個文件。
相關問題