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 define __C_FUNC callTheRightFunction(m,p,&getstate); しかし、ヘッダーファイルが定義されていないときに最初にヘッダーファイルを含めるため、おそらくそれらのいずれも含まれず、ランタイムエラーが生成されます。正しい方向への提案をいただければ幸いです。よろしくお願いします!

4

2 に答える 2

1

元の質問への追加に基づいて、どの関数もコンパイルされないかどうか疑問に思っていました。次に、ヘッダー ファイルをインクルードする前に__C__FUNCorを定義する必要があります。__kalman

#define __C__FUNC
#include "header.h"

ただし、何も定義しない場合にこの問題を回避するには、SOURCE ファイルで次のように定義を 1 つだけ使用する方法があります。

#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、2 番目の関数が使用され#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、次のようなコマンド ライン オプションとして使用するだけです (たとえば、 bcc32):

bcc32 /D"__GSTATE_USE_C_FUNCTION" hello.c

これにより、問題(*1)が回避され、両方のソース ファイルにインクルードするグローバル ヘッダー ファイルを作成する必要がなくなります。

于 2012-09-30T06:37:24.423 に答える
1

ここには問題はありません。

オプション:

  1. 同じことを異なる方法で行う ASM 関数と C 関数を挙げてください。正しいものを呼び出すには、 ifor switchor、神は禁じられています。?:
  2. 上記と同じ名前の設定。関数ポインタを使用します。ASM 関数のアドレスを割り当てると、このポインターを介した関数呼び出しはそこに移動します。C 関数のアドレスを割り当てると、呼び出しは同様に C 関数に送られます。
  3. 上記と同じ名前の設定。ASM または C 関数の名前に展開されるマクロを定義します。コンパイラのオプションを使用して、コンパイル時にマクロを定義できます。2 つの関数のいずれかを呼び出す必要があるコードでそのマクロを使用します。
  4. ASM および C 関数を別の .asm/.s および .c ファイルに配置します。コンパイル時に、コンパイル済みファイルのリストに 1 つのファイルを含めるか、他のファイルを含めます。
于 2012-09-30T06:18:53.637 に答える