私は Microsoft の CRT ソース コードを読んでおり、main() ルーチンの前に関数 __initstdio1 が実行される次のコードを思いつくことができます。
問題は、VC (VC++ コードではなく) で main() ルーチンに入る前にコードを実行する方法です。
#include <stdio.h>
#pragma section(".CRT$XIC",long,read)
int __cdecl __initstdio1(void);
#define _CRTALLOC(x) __declspec(allocate(x))
_CRTALLOC(".CRT$XIC") static pinit = __initstdio1;
int z = 1;
int __cdecl __initstdio1(void) {
z = 10;
return 0;
}
int main(void) {
printf("Some code before main!\n");
printf("z = %d\n", z);
printf("End!\n");
return 0;
}
出力は次のようになります。
Some code before main!
z = 10
End!
ただし、コードを理解できません。
.CRT$XIC でいくつかのグーグルを実行しましたが、運がありません。専門家が上記のコード セグメント、特に以下について説明してくれませんか。
- この行
_CRTALLOC(".CRT$XIC") static pinit = __initstdio1;
はどういう意味ですか? 変数 pinit の意味は何ですか? - コンパイル中に、コンパイラ (cl.exe) は次のような警告をスローします。
Microsoft (R) 32 ビット C/C++ 最適化コンパイラ バージョン 15.00.30729.01 for 80x86 Copyright (C) Microsoft Corporation. 全著作権所有。
stdmacro.c
stdmacro.c(9) : warning C4047: 'initializing' : 'int' differs in levels of indirection from 'int (__
cdecl *)(void)'
Microsoft (R) Incremental Linker Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
/out:stdmacro.exe
stdmacro.obj
警告メッセージを削除するには、どのような修正アクションを実行する必要がありますか?
前もって感謝します。
追加した:
コードを変更し、_PIFV として pinit に型を指定しました。これで、警告メッセージはなくなりました。
新しいコードは次のとおりです。
#include <stdio.h>
#pragma section(".CRT$XIC1",long,read)
int __cdecl __initstdio1(void);
typedef int (__cdecl *_PIFV)(void);
#define _CRTALLOC(x) __declspec(allocate(x))
_CRTALLOC(".CRT$XIC1") static _PIFV pinit1 = __initstdio1;
int z = 1;
int __cdecl __initstdio1(void) {
z = 100;
return 0;
}
int main(void) {
printf("Some code before main!\n");
printf("z = %d\n", z);
printf("End!\n");
return 0;
}