5

ヘッダー ファイルで既に定義されている関数を .c ファイルで再定義できるようにしたいと考えています。weakref 属性に関する GCC マニュアルによると:

この効果は、エイリアスへのすべての参照を別の翻訳単位に移動し、エイリアスの名前をエイリアス化されたシンボルに変更し、それを弱いものとして宣言し、2 つの別個の翻訳単位をコンパイルし、それらに対して再読み込み可能なリンクを実行することと同じです。

それはまさに私がやりたいことのように聞こえます。ただし、次の例はエラーでコンパイルされません。

tpp.c:18:13: エラー: 'foo' の再定義 tpp.c:6:13: 注: 'foo' の以前の定義はここにありました

#include <sys/types.h>
#include <stdio.h>

/* this will be in a header file */
static void foo(void) __attribute__ ((weakref ("_foo")));

static void _foo(void)
{
    printf("default foo\n");
}

/* in a .c file #including the header mentioned above */
#define CUSTOM_FOO

#ifdef CUSTOM_FOO
static void foo(void)
{ 
    printf("user defined foo.\n");
}
#endif

int main(int argc, char **argv)
{
    printf("calling foo.\n");
    foo();
}

これを正しく使用していますか?私は何が欠けていますか?

gcc バージョン 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)

4

1 に答える 1

1

私が理解している限りでは、その関数を extern として定義する必要があります。次に、次のように機能します。

user@horst:$ cat weakref.c

#include <sys/types.h>
#include <stdio.h>

/* this will be in a header file */
extern void foo(void) __attribute__ ((weak, alias ("_foo")));

void _foo(void)
{
    printf("default foo\n");
}

int main(int argc, char **argv)
{
    printf("calling foo.\n");
    foo();
}

user@horst:$ gcc weakref.c 
user@horst:$ ./a.out 
calling foo.
default foo
user@horst:$ cat weakrefUser.c
#include <stdio.h>
/* in a .c file #including the header mentioned above */
#define CUSTOM_FOO

#ifdef CUSTOM_FOO
void foo(void)
{ 
    printf("user defined foo.\n");
}
#endif
user@horst:$ gcc -c weakrefUser.c 
user@horst:$ gcc -c weakref.c 
user@horst:$ gcc weakref.o weakrefUser.o 
user@horst:$ ./a.out 
calling foo.
user defined foo.

注 1: 静的関数では機能しません。weak 属性の場合、グローバルである必要があります。

注 2: 弱いシンボルは、ELF ターゲットに対して「のみ」サポートされています。

于 2013-01-08T14:16:56.260 に答える