significado - __tribuir__((constructor)) equivalente en VC?
palabras que terminen en buir (4)
Me preguntaba si es posible usar constructores de C en VC del mismo modo que es posible usarlos en GCC. El modo gcc es bastante directo usando la palabra clave attribute . Desafortunadamente, VC no parece saber esta palabra clave, ya que no soy un programador de Win32. Me pregunto si existe algún tipo de palabra clave equivalente para tales cosas. Solo para tener en cuenta: este es un programa C, no un C ++ o un C # incluso (ya que era bastante fácil hacerlo en esos idiomas)
Alguien tiene una pista?
Gracias por adelantado.
El código Abajo C demuestra cómo definir una función vacía (nula) a ser llamada en el tiempo de carga del programa / biblioteca, antes de que se ejecute la principal.
Para MSVC, esto coloca un puntero a la función en la sección de inicializador de usuario (.CRT $ XCU), básicamente lo mismo que hace el compilador para las llamadas de constructor para objetos estáticos de C ++. Para GCC, usa un atributo de constructor.
// 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;
}
Intenté la última respuesta en MSVC como
#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
pero INITIALIZER (f) no puede aparecer en 2 archivos diferentes con el mismo nombre de función pasado a INITIALIZER, la siguiente definición permitirá que
#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
No creo que haya una manera de evitar el uso de las características de C ++ con MSVC. (El soporte C de MSVC es una mierda de todos modos).
No probado, pero esto debería al menos permitir que el mismo código funcione tanto en MSVC como en 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() {
...
}
Probablemente estés interesado en DllMain .