プラットフォームによって異なります。
GCC を使用している場合は、関数を で宣言できます__attribute__((constructor))
。この関数は、動的ライブラリからでもメインの前に呼び出されます。
__attribute__((constructor))
void my_init()
{
/* do stuff; */
}
詳細については、 GCC のドキュメントとこの SO の質問を参照してください。
それほど単純ではありませんが、VC でもそれを行う方法がいくつかあります。(このSOの質問を参照してください)
EDIT:サードパーティのライブラリにリンクすると、init関数が呼び出される場合があります。ライブラリがC言語であっても、それを検出するための移植可能で一般的な方法はありません。また、ライブラリがメインの開始前に呼び出されることに依存する可能性があるため、おそらくそれを台無しにしたくないでしょう。
何かを呼び出すかどうかを本当に知りたい場合は、バイナリ内を調べる必要があります。ELF ファイルには、開始時に呼び出される関数への「ポインター」を含むセクションがあり、objdump ( ).init_array
を使用してダンプできます。objdump -s -j .init_array <binary>
WindowsのPEファイルにも同様のセクションがあると思いますが、それらを扱ったことはありません。
EDIT2 :main()
関数はコードを開始します。しかし、それが実行される前であっても、やるべきことがあります。プログラムをコンパイルすると、コンパイラはプログラムの前に実行されるコードを追加し、main()
プログラムの環境 (スタック、C ライブラリなど) を初期化します。
Linux では、これは主に関数_start
とによって提供されます_init
。また、機能として、関数内で関数を呼び出すようにコンパイラーに指示することもできます_init
。
動的ライブラリには関数がありませんが、ライブラリがロードされたときに呼び出される_start
関数がまだあります。_init
また、いくつかのユーザー関数への呼び出しもそこに含めることができます。
静的ライブラリの場合、リンカーがプログラムから呼び出されない関数を削除する可能性があるため、もう少し複雑になります。しかし、(ライブラリ コードから間接的にでも) 呼び出されるか、ライブラリ内のどこかで参照され、実際には呼び出されない場合は、最終的にバイナリになり、 before で呼び出されmain()
ます。
とに関するいくつかの情報は_start
、ここで見つける_init
ことができます。
Windows では、コンパイラとリンカーは異なりますが、同様の方法で動作するはずです。