cerbert
29-03-2007, 09:51
Buon giorno a tutti,
di recente mi sto occupando della transizione di una applicazione piuttosto massiccia da Visual Studio 6.0 a Visual Studio 2005.
Durante tale transizione, quando si tratta di compilare delle dll, ottengo il seguente warning:
Warning 1 warning C4003: not enough actual parameters for macro '_IMPLEMENT_RUNTIMECLASS' 16
Andando a verificare scopro che il warning viene causato da delle macro custom da noi fatte per creare degli "_IMPLEMENT_RUNTIME_CUSTOM" in modo da poter serializzare nell'applicazione principale tipi di dati creati nelle dll.
Ecco un esempio di macro custom
#define IMPLEMENT_SERIAL_EXP_CELLMODEL(class_name, base_class_name, wSchema) \
CObject* PASCAL class_name::CreateObject() \
{ return new class_name; } \
_IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, \
class_name::CreateObject) \
AFX_CLASSINIT _init_##class_name(RUNTIME_CLASS(class_name)); \
CELL_MODEL_IMPEXP CArchive& AFXAPI operator>>(CArchive& ar, class_name* &pOb) \
{ pOb = (class_name*) ar.ReadObject(RUNTIME_CLASS(class_name)); \
return ar; }
Il problema è che la definizione di _IMPLEMENT_RUNTIMECLASS (in AFX.H) sembra cambiata molto dalla precedente versione di MFC
#define _IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew) \
CRuntimeClass* PASCAL class_name::_GetBaseClass() \
{ return RUNTIME_CLASS(base_class_name); } \
AFX_COMDAT AFX_DATADEF CRuntimeClass class_name::class##class_name = { \
#class_name, sizeof(class class_name), wSchema, pfnNew, \
&class_name::_GetBaseClass, NULL }; \
CRuntimeClass* class_name::GetRuntimeClass() const \
{ return RUNTIME_CLASS(class_name); } \
alla attuale
#define _IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew, class_init) \
CRuntimeClass* PASCAL class_name::_GetBaseClass() \
{ return RUNTIME_CLASS(base_class_name); } \
AFX_COMDAT CRuntimeClass class_name::class##class_name = { \
#class_name, sizeof(class class_name), wSchema, pfnNew, \
&class_name::_GetBaseClass, NULL, class_init }; \
CRuntimeClass* PASCAL class_name::GetThisClass() \
{ return _RUNTIME_CLASS(class_name); } \
CRuntimeClass* class_name::GetRuntimeClass() const \
{ return _RUNTIME_CLASS(class_name); } \
c'è, infatti, quell'ultimo parametro in più "class_init" che ignoro completamente cosa faccia e che tipo di argomento accetti... o, meglio, suppongo che accetti un parametro di tipo AFX_CLASSINIT, ma non so a quale valore debba essere inizializzato tale parametro.
Ovviamente, se la precedente forma di _IMPLEMENT_RUNTIMECLASS era a malapena documentata in qualche FAQ ed in qualche paginetta di codeguru, la attuale è ASSOLUTAMENTE ignota ai più.
Se qualcuno, certamente più preparato di me, riesce a darmi qualche dritta, avrà tutta la mia gratitudine.
di recente mi sto occupando della transizione di una applicazione piuttosto massiccia da Visual Studio 6.0 a Visual Studio 2005.
Durante tale transizione, quando si tratta di compilare delle dll, ottengo il seguente warning:
Warning 1 warning C4003: not enough actual parameters for macro '_IMPLEMENT_RUNTIMECLASS' 16
Andando a verificare scopro che il warning viene causato da delle macro custom da noi fatte per creare degli "_IMPLEMENT_RUNTIME_CUSTOM" in modo da poter serializzare nell'applicazione principale tipi di dati creati nelle dll.
Ecco un esempio di macro custom
#define IMPLEMENT_SERIAL_EXP_CELLMODEL(class_name, base_class_name, wSchema) \
CObject* PASCAL class_name::CreateObject() \
{ return new class_name; } \
_IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, \
class_name::CreateObject) \
AFX_CLASSINIT _init_##class_name(RUNTIME_CLASS(class_name)); \
CELL_MODEL_IMPEXP CArchive& AFXAPI operator>>(CArchive& ar, class_name* &pOb) \
{ pOb = (class_name*) ar.ReadObject(RUNTIME_CLASS(class_name)); \
return ar; }
Il problema è che la definizione di _IMPLEMENT_RUNTIMECLASS (in AFX.H) sembra cambiata molto dalla precedente versione di MFC
#define _IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew) \
CRuntimeClass* PASCAL class_name::_GetBaseClass() \
{ return RUNTIME_CLASS(base_class_name); } \
AFX_COMDAT AFX_DATADEF CRuntimeClass class_name::class##class_name = { \
#class_name, sizeof(class class_name), wSchema, pfnNew, \
&class_name::_GetBaseClass, NULL }; \
CRuntimeClass* class_name::GetRuntimeClass() const \
{ return RUNTIME_CLASS(class_name); } \
alla attuale
#define _IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew, class_init) \
CRuntimeClass* PASCAL class_name::_GetBaseClass() \
{ return RUNTIME_CLASS(base_class_name); } \
AFX_COMDAT CRuntimeClass class_name::class##class_name = { \
#class_name, sizeof(class class_name), wSchema, pfnNew, \
&class_name::_GetBaseClass, NULL, class_init }; \
CRuntimeClass* PASCAL class_name::GetThisClass() \
{ return _RUNTIME_CLASS(class_name); } \
CRuntimeClass* class_name::GetRuntimeClass() const \
{ return _RUNTIME_CLASS(class_name); } \
c'è, infatti, quell'ultimo parametro in più "class_init" che ignoro completamente cosa faccia e che tipo di argomento accetti... o, meglio, suppongo che accetti un parametro di tipo AFX_CLASSINIT, ma non so a quale valore debba essere inizializzato tale parametro.
Ovviamente, se la precedente forma di _IMPLEMENT_RUNTIMECLASS era a malapena documentata in qualche FAQ ed in qualche paginetta di codeguru, la attuale è ASSOLUTAMENTE ignota ai più.
Se qualcuno, certamente più preparato di me, riesce a darmi qualche dritta, avrà tutta la mia gratitudine.