我正在阅读Microsoft的CRT源代码,我可以提出以下代码,其中函数__initstdio1将在main()例程之前执行.
问题是,如何在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;
}
Run Code Online (Sandbox Code Playgroud)
输出将是:
Some code before main!
z = 10
End!
Run Code Online (Sandbox Code Playgroud)
但是,我无法理解代码.
我在.CRT $ XIC上做了一些谷歌,但没有找到运气.有些专家可以向我解释上面的代码段,尤其是以下内容:
_CRTALLOC(".CRT$XIC") static pinit = __initstdio1;
是什么意思?变量pinit有什么意义?Microsoft(R)32位C/C++优化编译器版本15.00.30729.01 for 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
Run Code Online (Sandbox Code Playgroud)
删除警告消息需要采取哪些纠正措施?
提前致谢.
添加:
我修改了代码并将类型设为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;
}
Run Code Online (Sandbox Code Playgroud)
一个简单的方法来做到这一点.
#include <iostream>
int before_main()
{
std::cout << "before main" << std::endl;
return 0;
}
static int n = before_main();
void main(int argc, char* argv[])
{
std::cout << "in main" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
这里有一些信息(搜索 CRT)。变量的意义pinit
是没有,它只是放置在可执行文件中的一段数据,运行时可以在其中找到它。但是,我建议您给它一个类型,如下所示:
_CRTALLOC(".CRT$XIC") static void (*pinit)()=...
Run Code Online (Sandbox Code Playgroud)
链接器警告可能只是警告您有一个具有int
返回类型的函数,但不返回任何内容(可能您最好将返回类型更改为void
)。