Avertissement du compilateur (niveau 1) C4378
Les pointeurs fonction sont indispensables à l'exécution des initialiseurs ; utilisez System::ModuleHandle::ResolveMethodHandle à la place
Sous /clr, les symboles d’initialiseur contiennent des jetons de fonction, et non des pointeurs de fonctions. Vous devez convertir des jetons en pointeurs à l’aide ResolveMethodHandlede .
Exemples
L’exemple suivant génère l’erreur 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();
}
L’exemple suivant montre comment résoudre 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();
}