Advertencia del compilador (nivel 1) C4378
Para ejecutar los inicializadores, debe obtener punteros de funciones; utilice System::ModuleHandle::ResolveMethodHandle
En /clr, los símbolos de los inicializadores contienen tokens de función, no punteros de funciones. Por consiguiente, es preciso convertir los tokens en punteros mediante ResolveMethodHandle.
Ejemplos
El siguiente ejemplo genera la advertencia C4378.
// C4378.cpp
// compile with: /W1 /clr /c
typedef void (__cdecl *PF)(void);
int cxpf = 0; // number of destructors to call
PF pfx[200]; // ptrs to those dtors, watch for overflow
int myexit (PF pf) {
pfx[cxpf++] = pf;
return 0;
}
struct A {
A() {}
~A() {}
};
A aaaa;
#pragma data_seg(".mine$a")
PF InitSegStart = (PF)1;
#pragma data_seg(".mine$z")
PF InitSegEnd = (PF)1;
#pragma data_seg()
void InitializeObjects () {
PF *x = &InitSegStart;
for (++x ; x < &InitSegEnd ; ++x)
if (*x)
(*x)();
}
#pragma init_seg(".mine$m",myexit) // C4378
A bbbb; // crash
int main () {
InitializeObjects();
}
En el ejemplo siguiente se muestra cómo resolver la advertencia C4378.
// C4378_b.cpp
// compile with: /clr
#pragma warning(disable:4378)
using namespace System;
typedef void (__cdecl *PF)(void);
typedef void (__clrcall * CLRPF)(void);
int cxpf = 0; // number of destructors we need to call
PF pfx[200]; // ptrs to those dtors. Watch out for overflow!
ref class TypeClassHolder {
public:
static TypeClassHolder ^typeClass = gcnew TypeClassHolder();
};
CLRPF FuncTokenToFuncPtr(PF tknFunc) {
ModuleHandle type =
Type::GetTypeFromHandle(Type::GetTypeHandle(TypeClassHolder::typeClass))->Module->ModuleHandle;
return (CLRPF)type.ResolveMethodHandle((int)(size_t)(tknFunc)).GetFunctionPointer().ToPointer();
}
int myexit (PF pf) {
pfx[cxpf++] = pf;
return 0;
}
struct A {
A() {}
~A() {}
};
A aaaa;
#pragma data_seg(".mine$a")
PF InitSegStart = (PF)1;
#pragma data_seg(".mine$z")
PF InitSegEnd = (PF)1;
#pragma data_seg()
void InitializeObjects () {
PF *x = &InitSegStart;
for (++x ; x < &InitSegEnd ; ++x)
if(*x) {
CLRPF realppfunc;
realppfunc = FuncTokenToFuncPtr(*x);
(realppfunc)();
}
}
#pragma init_seg(".mine$m",myexit)
A bbbb; // constructor call succeeds
int main () {
InitializeObjects();
}