Error registering a class that is in a namespace

Forum for posting problems using QxOrm library

Error registering a class that is in a namespace

Postby ukindler » Mon Mar 28, 2011 2:31 pm

Hi,

I have a problem to register a class to QxOrm that is inside of a namespace and I have no glue what I'm doing wrong here. I work on a Windows system with MinGW GCC 4.5.1. The error message is:

Code: Select all
QxOrmWellPlateType.h:39:1: error: 'G_QX_REGISTER_FACTORY_QtLabb' has not been declared
QxOrmWellPlateType.cpp:16:1: error: 'G_QX_REGISTER_FACTORY_QtLabb' has not been declared


This is the header file of the class:

Code: Select all
#ifndef QxOrmWellPlateTypeH
#define QxOrmWellPlateTypeH

#include "export.h"

namespace QtLabb
{
class TEST_OPENCV_DLL_EXPORT CQxOrmWellPlateType
{
public:
   QString m_TypeName;
   int m_RowCount;
   int m_ColumnCount;
   double m_RowSpacing;
   double m_ColumnSpacing;

   CQxOrmWellPlateType();
   virtual ~CQxOrmWellPlateType();
}; // class CQxOrmWellPlateType

}

QX_REGISTER_PRIMARY_KEY(QtLabb::CQxOrmWellPlateType, QString)
QX_REGISTER_HPP_TEST_OPENCV(QtLabb::CQxOrmWellPlateType, qx::trait::no_base_class_defined, 0)

//---------------------------------------------------------------------------
#endif // QxOrmWellPlateTypeH


This is the code of the source file of this class:
Code: Select all
#include "precompiled.h"
#include "QxOrmWellPlateType.h"
#include <QxMemLeak.h>

QX_REGISTER_CPP_TEST_OPENCV(QtLabb::CQxOrmWellPlateType);

namespace qx {
template <> void register_class(QxClass<QtLabb::CQxOrmWellPlateType>& t)
{

}
}

namespace QtLabb
{
CQxOrmWellPlateType::CQxOrmWellPlateType() { }

CQxOrmWellPlateType::~CQxOrmWellPlateType() { }
}


This is my export.h file:

Code: Select all
#ifndef exportH
#define exportH

#ifdef _BUILDING_TEST_OPENCV
#define TEST_OPENCV_DLL_EXPORT QX_DLL_EXPORT_HELPER
#define QX_REGISTER_HPP_TEST_OPENCV QX_REGISTER_HPP_EXPORT_DLL
#define QX_REGISTER_CPP_TEST_OPENCV QX_REGISTER_CPP_EXPORT_DLL
#else // _BUILDING_TEST_OPENCV
#define TEST_OPENCV_BLOG_DLL_EXPORT QX_DLL_IMPORT_HELPER
#define QX_REGISTER_HPP_TEST_OPENCV QX_REGISTER_HPP_IMPORT_DLL
#define QX_REGISTER_CPP_TEST_OPENCV QX_REGISTER_CPP_IMPORT_DLL
#endif // _BUILDING_TEST_OPENCV

#endif // exportH


And this is my precompiled.h file:

Code: Select all
#ifndef precompiledH
#define precompiledH

#include <QxOrm.h>
#include "export.h"

#endif // precompiledH


If I move the CQxOrmWellPlateType class out of the QtLabb namespace, then everything works fine. In eclipse I can use the macro expansion feature to get the complete expansion of the register macro. In the expansion I can see, that the register macro creates a reference to a QxFactory object with the name G_QX_REGISTER_FACTORY_QtLabb::CQxOrmWellPlateType. But this is not a valid object name in C++. So what should I do to register a class that is inside of a namespace?

Code: Select all
namespace qx { namespace trait { \
template <> \
struct is_qx_registered< QtLabb::CQxOrmWellPlateType > { enum { value = true }; }; \
} } \
namespace qx { namespace trait { \
template <> \
struct get_class_name< QtLabb::CQxOrmWellPlateType > \
{ \
   static inline const char * get() \
   { \
      static std::string result; \
if (! result.empty()) { return result.c_str(); } \
result = std::string("QtLabb::CQxOrmWellPlateType");; \
      return result.c_str(); \
   } \
   static inline const char * get_xml_tag() \
{ \
   static std::string result_xml; \
   if (! result_xml.empty()) { return result_xml.c_str(); } \
   result_xml = std::string(get_class_name::get()); \
   boost::replace_all(result_xml, std::string("<"), std::string("-")); \
   boost::replace_all(result_xml, std::string(">"), std::string("-")); \
   boost::replace_all(result_xml, std::string(", "), std::string("_")); \
   boost::replace_all(result_xml, "::", "."); \
   boost::replace_all(result_xml, " ", ""); \
   return result_xml.c_str(); \
}; \
}; \
} } \
namespace qx { namespace trait { \
template <> \
class get_base_class< QtLabb::CQxOrmWellPlateType > \
{ public: typedef qx::trait::no_base_class_defined type; }; \
} } \
extern qx::QxFactory< QtLabb::CQxOrmWellPlateType > G_QX_REGISTER_FACTORY_QtLabb::CQxOrmWellPlateType; \
 \
 \
BOOST_CLASS_VERSION(QtLabb::CQxOrmWellPlateType, 0) \
 extern template class  qx::QxDataMemberX< QtLabb::CQxOrmWellPlateType >;  \
 extern template class  qx::QxSingleton< qx::QxDataMemberX< QtLabb::CQxOrmWellPlateType > >;  \
 extern template class  qx::QxClass< QtLabb::CQxOrmWellPlateType >;  \
 extern template class  qx::QxSingleton< qx::QxClass< QtLabb::CQxOrmWellPlateType > >;  \
 extern template class  boost::serialization::extended_type_info_typeid< QtLabb::CQxOrmWellPlateType >;  \
 extern template class  boost::serialization::singleton< boost::serialization::extended_type_info_typeid< QtLabb::CQxOrmWellPlateType > >;  \
 extern template class  boost::archive::detail::iserializer< boost::archive::polymorphic_iarchive, QtLabb::CQxOrmWellPlateType >;  \
 extern template class  boost::serialization::singleton< boost::archive::detail::iserializer< boost::archive::polymorphic_iarchive, QtLabb::CQxOrmWellPlateType > >;  \
 extern template class  boost::archive::detail::oserializer< boost::archive::polymorphic_oarchive, QtLabb::CQxOrmWellPlateType >;  \
 extern template class  boost::serialization::singleton< boost::archive::detail::oserializer< boost::archive::polymorphic_oarchive, QtLabb::CQxOrmWellPlateType > >;  \
 extern template class  boost::archive::detail::pointer_iserializer< boost::archive::polymorphic_iarchive, QtLabb::CQxOrmWellPlateType >;  \
 extern template class  boost::serialization::singleton< boost::archive::detail::pointer_iserializer< boost::archive::polymorphic_iarchive, QtLabb::CQxOrmWellPlateType > >;  \
 extern template class  boost::archive::detail::pointer_oserializer< boost::archive::polymorphic_oarchive, QtLabb::CQxOrmWellPlateType >;  \
 extern template class  boost::serialization::singleton< boost::archive::detail::pointer_oserializer< boost::archive::polymorphic_oarchive, QtLabb::CQxOrmWellPlateType > >;  \
 \
 \
 extern template struct  boost::archive::detail::save_pointer_type< boost::archive::polymorphic_oarchive, QtLabb::CQxOrmWellPlateType * >;  \
 extern template class  boost::serialization::singleton< boost::archive::detail::save_pointer_type< boost::archive::polymorphic_oarchive, QtLabb::CQxOrmWellPlateType * > >;  \
 extern template struct  boost::archive::detail::load_pointer_type< boost::archive::polymorphic_iarchive, QtLabb::CQxOrmWellPlateType * >;  \
 extern template class  boost::serialization::singleton< boost::archive::detail::load_pointer_type< boost::archive::polymorphic_iarchive, QtLabb::CQxOrmWellPlateType * > >;  \
 \
 \
 \
 \
 \
 \
 \
namespace boost { namespace serialization { \
 void serialize(boost::archive::polymorphic_oarchive & ar, QtLabb::CQxOrmWellPlateType & t, const unsigned int file_version) BOOST_USED; \
} } \
namespace boost { namespace serialization { \
 void serialize(boost::archive::polymorphic_iarchive & ar, QtLabb::CQxOrmWellPlateType & t, const unsigned int file_version) BOOST_USED; \
} } \
namespace boost { namespace serialization { \
template <class Archive> \
void serialize(Archive & ar, QtLabb::CQxOrmWellPlateType & t, const unsigned int file_version); \
} } \
 \
 \
 \
 \
 \
 \
 \
namespace qx { template <>  void register_class(QxClass< QtLabb::CQxOrmWellPlateType > & t) BOOST_USED; }


Any Idea what is wrong with my code. Is there something I missed?
ukindler
 

Re: Error registering a class that is in a namespace

Postby ukindler » Mon Mar 28, 2011 2:45 pm

Hi,

I found a solution but I'm not sure if it is the right one. I added the following line to my export.h file:

Code: Select all
#define QX_REGISTER_COMPLEX_HPP_TEST_OPENCV QX_REGISTER_COMPLEX_CLASS_NAME_HPP_EXPORT_DLL


The QX_REGISTER_COMPLEX_CLASS_NAME_HPP_EXPORT_DLL macor takes an additional parameter that contains a formatted class name. So I use the following code now to register my class:

Code: Select all
QX_REGISTER_COMPLEX_HPP_TEST_OPENCV(QtLabb::CQxOrmWellPlateType, qx::trait::no_base_class_defined, 0, QtLabbCQxOrmWellPlateType)


Is this the right way? At least it compiles fine.
ukindler
 

Re: Error registering a class that is in a namespace

Postby QxOrm admin » Tue Mar 29, 2011 7:27 am

Hi,

You have found the solution ;)
When your class is inside a namespace, you have to use "QX_REGISTER_COMPLEX_CLASS_NAME_XXXXXX" macros...

You have a sample in the directory : "./test/qxDllSample/dll1/" with the class "CPerson" in the namespace "qx::test".

Here the "export.h" file of dll1 project :
Code: Select all
#ifdef _QX_BUILDING_DLL1
#define QX_REGISTER_HPP_QX_DLL1 QX_REGISTER_HPP_EXPORT_DLL
#define QX_REGISTER_CPP_QX_DLL1 QX_REGISTER_CPP_EXPORT_DLL
#define QX_REGISTER_COMPLEX_CLASS_NAME_HPP_QX_DLL1 QX_REGISTER_COMPLEX_CLASS_NAME_HPP_EXPORT_DLL
#define QX_REGISTER_COMPLEX_CLASS_NAME_CPP_QX_DLL1 QX_REGISTER_COMPLEX_CLASS_NAME_CPP_EXPORT_DLL
#else // _QX_BUILDING_DLL1
#define QX_REGISTER_HPP_QX_DLL1 QX_REGISTER_HPP_IMPORT_DLL
#define QX_REGISTER_CPP_QX_DLL1 QX_REGISTER_CPP_IMPORT_DLL
#define QX_REGISTER_COMPLEX_CLASS_NAME_HPP_QX_DLL1 QX_REGISTER_COMPLEX_CLASS_NAME_HPP_IMPORT_DLL
#define QX_REGISTER_COMPLEX_CLASS_NAME_CPP_QX_DLL1 QX_REGISTER_COMPLEX_CLASS_NAME_CPP_IMPORT_DLL
#endif // _QX_BUILDING_DLL1


I will add this question in the FAQ of the website...
QxOrm admin
 


Return to QxOrm - Help

Who is online

Users browsing this forum: No registered users and 7 guests