2


So here's my problem. I'm writing web browser plugin in Firebreath. Plugin has to connect to different databases (Firebird, MS SQL, My SQL etc.) depending on client request. So I'm creating class to manage connection to right DB. To connect to Firebird I'm trying to use IBPP. I managed to connect to FB using IBPP in simple test project. But now when I'm doing something much more complex I've got this strange linker error LNK2019.

Exact error message is:

Error   2   error LNK2019: unresolved external symbol "class IBPP::Ptr<class IBPP::IDatabase>
__cdecl IBPP::DatabaseFactory(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)
" (?DatabaseFactory@IBPP@@YA?AV?$Ptr@VIDatabase@IBPP@@@1@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@000000@Z)
referenced in function "class IBPP::Ptr<class IBPP::IDatabase>
__cdecl IBPP::DatabaseFactory(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)"
(?DatabaseFactory@IBPP@@YA?AV?$Ptr@VIDatabase@IBPP@@@1@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@000@Z)
C:\ff-extensions\F4U\build\projects\F4UConv\Connections.obj F4UConv



Code for my connections looks like this:
Header

#ifndef Connections_h
#define Connections_h

#include <cstdarg>
#include <string>

#include "ibpp\ibpp.h"
#include "..\Logger\Logger.h"

using namespace std;

namespace Connections{

    class Connection {
        public:
            void set_logger(Logger::Logger *logger);

            virtual bool setup_connection(string machine, string db_path, string login, string passwd)=0;
            virtual bool connect()=0;
            virtual bool disconnect()=0;

            virtual bool setup_statement(string sql_statement, const char *fmt, ...)=0;

            template <class Statement>
            Statement execute_statement();

        protected:
            string machine;
            string db_path;
            string login;
            string passwd;
            Logger::Logger *logger;

    };

    class FB_Connection : public Connection {
        public:
            ~FB_Connection();

            bool setup_connection(string machine, string db_path, string login, string passwd);
            bool connect();
            bool disconnect();

            bool setup_statement(string sql_statement, const char *fmt, ...);

            template <class Statement>
            Statement execute_statement();

        private:
            IBPP::Database db;
    };
};

#endif Connections_h



Source

#include "Connections.h"

namespace Connections{

    void Connection::set_logger(Logger::Logger *logger){
        this->logger = logger;
    }

    FB_Connection::~FB_Connection(){
        if(this->db->Connected()){
            this->disconnect();
        }
        db->Drop();
    }

    bool FB_Connection::setup_connection(string machine, string db_path, string login, string passwd){
        this->machine = machine;
        this->db_path = db_path;
        this->login = login;
        this->passwd = passwd;

        try{
            this->db = IBPP::DatabaseFactory(this->machine, this->db_path, this->login, this->passwd);

            this->db->Create(3);
        }catch(IBPP::Exception& e){
            if(logger != nullptr){
                this->logger->log(Logger::LogMsgValue[Logger::E_LOGMSG_000002]);
                this->logger->log(Logger::LEVEL_ERROR, e.ErrorMessage());
            }
            return false;
        }

        return true;
    }

    bool FB_Connection::connect(){
        return true;
    }

    bool FB_Connection::disconnect(){
        return true;
    }

    bool FB_Connection::setup_statement(string sql_statement, const char *fmt, ...){
        return true;
    }

    template <class Statement>
    Statement FB_Connection::execute_statement(){
        return this;
    }
}



I'm googling for two days and still don't know what's the problem. I understand what LNK2019 error means but don't know why it occurs in this case.
The line that generate this error is:

this->db = IBPP::DatabaseFactory(this->machine, this->db_path, this->login, this->passwd);

Can anyone show me what's wrong?
Oh, and I'm using Visual Studio 2012 Express.

Michał
  • 21
  • 2

1 Answers1

0

You are trying to access the method in the source for which you haven't provided the definition in the connection namespace , i.e

This method :

DatabaseFactory(this->machine, this->db_path, this->login, this->passwd);

Provide a definition for it in the connection namespace.

Write using namespace connections; in the source file.

0decimal0
  • 3,884
  • 2
  • 24
  • 39
  • That's not that. DatabaseFactory is a method defined in namespace IBPP in ibpp.h library. – Michał Jul 24 '13 at 13:49
  • Then you should include ibpp.h in the source file. And why did you include two namespaces definitions ... one in your header and second in your source ??? – 0decimal0 Jul 24 '13 at 13:51
  • It's included in header file Connections.h so it's also in source file Connections.cpp – Michał Jul 24 '13 at 13:53
  • The namespace in source file is not a redefinition of namespace from header or second definition of this namespace, it's a correct way of coding. You use command "using namespace" when you're using it not implementing. Although this should compile and work also. – Michał Jul 24 '13 at 14:05
  • @Michał I don't think by including ibpp.h in the definition of `connection.h` also includes the definition of databasefactory in the source ... just by including `connections.h` ... that is where the linker is unable to resolve the name . – 0decimal0 Jul 24 '13 at 14:12
  • Before answering I've checked that I was right. So I tried to compile your version, it has generated maaaaaaannnnyyyy errors. Using "class class_name{...}" in source file again is indeed redefining class from header file, so for example compiler couldn't find properties from such class defined in header file. – Michał Jul 24 '13 at 14:14
  • I've tried to include ibpp.h to both header and source at the same time, still same linker error. – Michał Jul 24 '13 at 14:16
  • @Michał Yes you are right the class{..} is redefining so just use member functions . You are saying that this line `this->db = IBPP::DatabaseFactory(this->machine, this->db_path, this->login, this->passwd);` generates linker error , then what do you think could be the possible mistake? Except that it has definition somewhere that linker is unable to find ? – 0decimal0 Jul 24 '13 at 14:21
  • OK I've found temporary solution. I've added line `#include "ibpp\all_in_one.cpp"` to source file and it has compiled without erros. But I don't think it's a good solution. File `all_in_one.cpp` just include all headers and sources from IBPP library. Thing is I haven't found anything on the project IBPP page that would said about such use. They say to include just `ibpp.h`. Is there anyone who knows IBPP project good enough to explain me how to use it correctly? Or maybe the way I did it is a correct way? – Michał Jul 25 '13 at 08:48