VC中的__attribute __((构造函数))等效?

26 c visual-studio

我想知道是否可以在VC中使用C构造函数,因为可以在GCC中使用它们.使用attribute关键字的gcc方式非常简单,不幸的是VC似乎甚至不知道这个关键字,因为我不是Win32程序员,我想知道是否有某种等效的关键字用于这类事情.需要注意的是 - 这是一个C程序,而不是C++或C#甚至,(因为'在这些语言中很容易做到这一点)

有人知道吗?

提前致谢.

Joe*_*Joe 36

下面的C代码演示了如何在main执行之前定义在程序/库加载时调用的void(void)函数.

对于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;
}
Run Code Online (Sandbox Code Playgroud)

  • 这些构造函数将在新的Visual Studio版本构建中进行优化.它的遗憾和遗憾的未解决的bug.到目前为止我找到的唯一解决方法:项目属性> C/C++>优化>必须禁用整个程序优化(/ GL). (3认同)
  • @ user3042599.感谢您对MSVC 2015链接时优化问题提出了自己的看法.我编辑了代码示例,它应该没有问题,但由于使用了__pragma(),它现在需要MSVC 2008或更高版本. (2认同)

fox*_*337 5

您可能对DllMain感兴趣。

  • 即使在单个程序映像中,`__attribute__((constructor))` 也很有用;例如,在库和系统调用周围插入全局钩子,或者注册内置“插件”,或者初始化动态链接模块在其“DllMain”类似中所需的数据结构。 (7认同)

eph*_*ent 5

我认为没有办法避免在MSVC中使用C++功能.(无论如何,MSVC的C支持很糟糕.)

未经测试,但至少应该允许相同的代码在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() {
    ...
}
Run Code Online (Sandbox Code Playgroud)