c++linker-errorsunresolved-externalodb

ODB: unresolved external symbol error when including *.hxx file with common declarations


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?


Solution

  • 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.