I must use the ODB framework in my project. I have 2 files: station.hxx
and common.hxx
with following content:
common.hxx
#ifndef COMMON_HXX
#define COMMON_HXX
#include <string>
#pragma db value
struct ProcessAggregateName
{
#pragma db column("SHORTNAME")
std::string SHORTNAME;
#pragma db column("LONGNAME")
std::string LONGNAME;
#pragma db column("SECONDARYNAME")
std::string SECONDARYNAME;
};
#pragma db value
struct Reporting
{
#pragma db column("OPERATIONALLOG")
std::string OPERATIONALLOG;
#pragma db column("PRINTER")
std::string PRINTER;
#pragma db column("HIGHLIGHTING")
bool HIGHLIGHTING;
#pragma db column("REPORTTYPE")
std::string REPORTTYPE;
};
#endif // COMMON_HXX
station.hxx
#ifndef STATION_HXX
#define STATION_HXX
#include <string>
#include "common.hxx"
#pragma db object table("STATION")
class station
{
public:
station () {}
#pragma db id column("ID")
int ID;
#pragma db column("OPERATINGDOMAIN")
long OPERATINGDOMAIN;
#pragma db column("NAME")
ProcessAggregateName NAME;
#pragma db column("EXPORTBASICDATA")
bool EXPORTBASICDATA;
#pragma db column("EXPORTPROCESSDATA")
bool EXPORTPROCESSDATA;
#pragma db column("IMPORTBASICDATA")
bool IMPORTBASICDATA;
#pragma db column("IMPORTPROCESSDATA")
bool IMPORTPROCESSDATA;
#pragma db column("REPORTING")
Reporting REPORTING;
};
#endif // STATION_HXX
The reason for this: I want to use structures declared in common.hxx
also in other files, so I wanted to concentrate them in the same header file and include it whereever I need them. My problem: if I do it this way, I get linker errors like these:
error LNK2019: unresolved external symbol "public: static void __cdecl odb::access::composite_value_traits::bind(struct odb::mssql::bind *,struct odb::access::composite_value_traits::image_type &,enum odb::mssql::statement_kind)" (?bind@?$composite_value_traits@UProcessAggregateName@@$03@access@odb@@SAXPAU0mssql@3@AAUimage_type@123@W4statement_kind@43@@Z) referenced in function "public: static void __cdecl odb::access::object_traits_impl::bind(struct odb::mssql::bind *,struct odb::access::object_traits_impl::image_type &,enum odb::mssql::statement_kind)" (?bind@?$object_traits_impl@Vstation@@$03@access@odb@@SAXPAU0mssql@3@AAUimage_type@123@W4statement_kind@43@@Z)
error LNK2019: unresolved external symbol "public: static void __cdecl odb::access::composite_value_traits::init(struct odb::access::composite_value_traits::image_type &,struct ProcessAggregateName const &,enum odb::mssql::statement_kind)" (?init@?$composite_value_traits@UProcessAggregateName@@$03@access@odb@@SAXAAUimage_type@123@ABUProcessAggregateName@@W4statement_kind@mssql@3@@Z) referenced in function "public: static void __cdecl odb::access::object_traits_impl::init(struct odb::access::object_traits_impl::image_type &,class station const &,enum odb::mssql::statement_kind)" (?init@?$object_traits_impl@Vstation@@$03@access@odb@@SAXAAUimage_type@123@ABVstation@@W4statement_kind@mssql@3@@Z)
If I copy the declaration of ProcessAggregateName
and Reporting
into station.hxx
directly instead of including common.hxx
, everything goes fine. What do I do wrong and how can I declare commonly used structures in a single header and include it in multiple *.hxx files?
The odb
compiler/code generator creates three elements for the persistence layer - .hxx
, .ixx
and .cxx
files. The .hxx
and .ixx
files contain the declarations of the types that are needed to perform the persistence. These will satisfy the compiler when building - you tell it what the interface looks like.
However, in order to use the code, you need the implementation files (the definitions). These are only present in the .cxx
files.
Without the .cxx
files, you get the odb::access
… linker errors; these indicate that the code behind the declarations are missing.
Once you make sure that the .cxx
files are compiled and linked into your project, the compilation should succeed.