私の共有ライブラリでは、ロード時に特定の初期化を行う必要があります。私がGCC属性__attribute__ ((constructor))
で関数を定義すると、それは機能しません。つまり、共有ライブラリをリンクしているプログラムがロードされたときに呼び出されません。共有ライブラリのコンストラクタが動作しない
機能名を_init()
に変更すると機能します。明らかに_init()
と_fini()
の機能の使用は現在not recommendedです。
なぜ__attribute__ ((constructor))
がうまくいかないのですか?これは、Linux 2.6.9、gcc
バージョンである3.4.6
編集:.soのを構築するための
#include <stdio.h>
int smlib_count;
void __attribute__ ((constructor)) setup(void) {
smlib_count = 100;
printf("smlib_count starting at %d\n", smlib_count);
}
void smlib_count_incr() {
smlib_count++;
smlib_count++;
}
int smlib_count_get() {
return smlib_count;
}
:例えば
、のライブラリのコードは、この次のようであるとしましょう私は、次の操作を行います
gcc -fPIC -c smlib.c
ld -shared -soname libsmlib.so.1 -o libsmlib.so.1.0 -lc smlib.o
ldconfig -v -n .
ln -sf libsmlib.so.1 libsmlib.so
の.soは私がを更新する標準的な場所の一つではありませんので、を開き、別のプログラムから.soをリンクします。コンストラクタは呼び出されません。私が_init()
に変更すると動作します。
これは、関数定義で属性文字列を配置する場所と関連があります。あなたの中にはどこがありますか?私はそれのように動作するものを持っています: 'void __attribute__((コンストラクタ))コンストラクタ(){...}'。 'void'の後で' constructor() 'の前にあることに注意してください。 –
答えはありませんが、共有ライブラリコンストラクタは、 'main'が入力される前にプログラムの初期状態を混乱させるため、一般的に有害であると考えられます。最も悪名高い例は、OpenALです。これは、ALSAライブラリ/デバイスの状態で、アプリケーションが後でALSAデバイスを開くのを妨げるような状態になってしまいました(少なくとも一度は修正されていますが、わかりません)。適切なライブラリは、グローバルな状態を避けるために最善を尽くすべきであり、絶対に必要な場合は、ctorsではなく最初のライブラリ呼び出しで遅延初期化を使用する必要があります。 –
@Dan Fego、上記で提案したプレースメントを含め、さまざまなプレースメントを試しました。それでも動作しません。 – Manohar