visual-studio __attribute__((constructor)) 在 VC 中是等价的吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1113409/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
__attribute__((constructor)) equivalent in VC?
提问by Joe
I was wondering if it's possible to use C constructors in VC just as it is possible to use them in GCC.
The gcc way is quite straight using the __attribute__keyword, unfortunately VC doesn't seem to even know this keyword, as I'm not a Win32 programmer I wonder if there's some sort of equivalent keyword for such things.
Just to note - this is a C program, not a C++ or C# even, (as 'twas quite easy to do that in those languages)
我想知道是否可以在 VC 中使用 C 构造函数,就像可以在 GCC 中使用它们一样。
gcc 使用__attribute__关键字的方式非常直接,不幸的是 VC 似乎甚至不知道这个关键字,因为我不是 Win32 程序员,我想知道是否有某种等效的关键字用于此类事情。
请注意 - 这是一个 C 程序,甚至不是 C++ 或 C#,(因为在这些语言中很容易做到这一点)
回答by Joe
Below C code demonstrates how to define a void(void) function to be called at program/library load time, before main executes.
下面的 C 代码演示了如何在 main 执行之前定义要在程序/库加载时调用的 void(void) 函数。
For MSVC, this places a pointer to the function in the user initializer section (.CRT$XCU), basically the same thing the compiler does for the constructor calls for static C++ objects. For GCC, uses a constructor attribute.
对于 MSVC,这会在用户初始值设定项 (.CRT$XCU) 中放置一个指向函数的指针,这与编译器为静态 C++ 对象的构造函数调用所做的基本相同。对于 GCC,使用构造函数属性。
// Initializer/finalizer sample for MSVC and GCC/Clang.
// 2010-2016 Joe Lowe. Released into the public domain.
#include <stdio.h>
#include <stdlib.h>
#ifdef __cplusplus
#define INITIALIZER(f) \
static void f(void); \
struct f##_t_ { f##_t_(void) { f(); } }; static f##_t_ f##_; \
static void f(void)
#elif defined(_MSC_VER)
#pragma section(".CRT$XCU",read)
#define INITIALIZER2_(f,p) \
static void f(void); \
__declspec(allocate(".CRT$XCU")) void (*f##_)(void) = f; \
__pragma(comment(linker,"/include:" p #f "_")) \
static void f(void)
#ifdef _WIN64
#define INITIALIZER(f) INITIALIZER2_(f,"")
#else
#define INITIALIZER(f) INITIALIZER2_(f,"_")
#endif
#else
#define INITIALIZER(f) \
static void f(void) __attribute__((constructor)); \
static void f(void)
#endif
static void finalize(void)
{
printf( "finalize\n");
}
INITIALIZER( initialize)
{
printf( "initialize\n");
atexit( finalize);
}
int main( int argc, char** argv)
{
printf( "main\n");
return 0;
}
回答by ephemient
I don't think there's a way to avoid using C++ features with MSVC. (MSVC's C support sucks anyways.)
我认为没有办法避免在 MSVC 中使用 C++ 功能。(无论如何,MSVC 的 C 支持很糟糕。)
Untested, but this should at least allow the same code to work in both MSVC and GCC.
未经测试,但这至少应该允许相同的代码在 MSVC 和 GCC 中工作。
#if defined(_MSC_VER)
struct construct { construct(void (*f)(void)) { f(); } };
#define constructor(fn) \
void fn(void); static constructor constructor_##fn(fn)
#elif defined(__GNUC__)
#define constructor(fn)
void fn(void) __attribute__((constructor))
#endif
static constructor(foo);
void foo() {
...
}
回答by user7061528
I tried the last answer in MSVC like
我在 MSVC 中尝试了最后一个答案,例如
#ifdef _MSC_VER
#pragma section(".CRT$XCU",read)
#define INITIALIZER2_(f,p) \
static void f(void); \
__declspec(allocate(".CRT$XCU")) void (*f##_)(void) = f; \
__pragma(comment(linker,"/include:" p #f "_")) \
static void f(void)
#ifdef _WIN64
#define INITIALIZER(f) INITIALIZER2_(f,"")
#else
#define INITIALIZER(f) INITIALIZER2_(f,"_")
#endif
#else
#define INITIALIZER(f) \
static void f(void) __attribute__((constructor)); \
static void f(void)
#endif
but INITIALIZER(f) can't appear in 2 different files with the same function name passed to INITIALIZER, the following definition will allow that
但是 INITIALIZER(f) 不能出现在 2 个不同的文件中,并且传递给 INITIALIZER 的函数名相同,下面的定义将允许
#ifdef _MSC_VER
#define INITIALIZER(f) \
static void f();\
static int __f1(){f();return 0;}\
__pragma(data_seg(".CRT$XIU"))\
static int(*__f2) () = __f1;\
__pragma(data_seg())\
static void f()
#else
#define INITIALIZER(f) \
__attribute__((constructor)) static void f()
#endif

