2

いくつかの条件が満たされた場合にのみリリースにリンクされる、いくつかの異なるライブラリ/オブジェクトを含むモジュラー C プロジェクトがあります。このプロジェクトは PowerPC 用の GCC 3.4.4 でビルドされています。

したがって、私のプロジェクト全体に、他のモジュールの関数を使用する C ファイルがいくつかあります (これらのモジュールは必ずしもビルドに追加されるわけではありません)。したがって、これらの関数は extern として宣言されます。

リリースに応じて、関数自体を含むモジュールがリンクされているかどうかが異なります。未定義の参照を避けるために、これらの関数はアセンブラ マクロで弱いものとして宣言されます。

私はこれを例で示しようとしています:

ModuleA.c (コアモジュール)

extern void bar(void);
void foo(void)
{
    // Do some Stuff    
    bar();
}

ModuleB.c (オプションモジュール)

void bar(void)
{
    // Do some stuff
}

ModuleB は常に ModuleA にリンクされているわけではなく、一部の特定のリリース ビルドでのみリンクされています。したがって、3 番目の C ファイルがあります。

weakfuncs.c (コアモジュール)

#define WEAK(x,y) __asm__(".weak " #x "\n.set " #x "," #y "\n");
void empty_function(void);
__asm__("empty_function:\nblr\n");
WEAK(bar,empty_function)

このマクロを使用すると、プロジェクトは常にビルドされます (ModuleB がリンクされている場合は ModuleB から呼び出され、ModuleB がリンクbar()されていない場合は.bar()empty_function()

プロジェクト全体にこれらのケースがたくさんあるので、私の前任者はこれらすべての機能を に集めていましたweakfuncs.c

これまでのところ、これは私が再利用しているレガシーコードでした

ここで、MinGW (GCC 4.8.1) を使用して Windows 用にすべてをコンパイルしたいと思います。私の問題は、コンパイラがアセンブラ ディレクティブに問題があるように見えることです。

__asm__("empty_function:\nblr\n");

まったく機能していません (彼はコマンドを知りblrません) が、次のように C で空の関数を実装できるため、これは問題ではありません。

void empty_function(void)
{
    return;
}

WEAK マクロ自体

#define WEAK(x,y) __asm__(".weak " #x "\n.set " #x "," #y "\n");

問題なくコンパイルされますが、効果はありません。つまり、リンクされていない関数は、WEAKマクロを実行したとしても、「未定義の参照」を引き起こします。

これで、関数に次のように属性 weak を与える方法が gcc にあることがわかりました。

extern void bar() __attribute__((weak));

これは実際には機能しますが、適応が必要な関数がたくさんあるのでweakfuncs.c、マクロを使用してそれを行うことをお勧めします。

プレース全体ですべての関数宣言を変更せずに、アセンブラー ディレクティブまたは C でそうする方法はありますか?

4

1 に答える 1

1

これはどうですか?

void empty_function(void)
{
    return;
}
#define WEAK(x,y) extern void x() __attribute__((weak, alias(#y)));
于 2013-10-31T10:24:11.797 に答える