__attribute __((构造函数))在VC中等价吗?
我想知道是否可以在VC中使用C构造函数,就像在GCC中使用它们一样。 使用属性关键字gcc的方式是相当直接的,不幸的是VC似乎甚至不知道这个关键字,因为我不是一个Win32程序员我不知道是否有某种类似的关键字这样的事情。 只要注意 – 这是一个C程序,而不是C ++或C#甚至(在这些语言中很容易做到这一点)
任何人都有线索?
提前致谢。
下面的C代码演示了如何定义一个void(void)函数,在main执行之前在程序/库加载时调用。
对于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; }
我不认为有一种方法可以避免在MSVC中使用C ++特性。 (MSVC的C支持糟透了。)
未经testing,但是这应该至less允许相同的代码在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() { ... }
您可能对DllMain感兴趣。
我尝试了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
但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