我正在阅读微软的 CRT 源代码,我可以想出以下代码,其中函数 __initstdio1 将在 main() 例程之前执行。
问题是,如何在进入 VC 中的 main() 例程之前执行一些代码(不是 VC++ 代码)?
#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,适用于 80x86 版权所有 (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
需要采取哪些纠正措施来删除警告消息?
提前致谢。
添加:
我已经修改了代码并将 pinit 的类型指定为 _PIFV。现在警告信息消失了。
新代码如下:
#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;
}