Embedding a parser from a separate translation unit into another parser - c++

I am trying to reuse a parser (named parser1_rule) that I have isolated in a translation unit (unit1.h/unit1.cpp), into another parser (name trace_parser). However I get a warning and an error message (reproduced and reformated below for easier reading) stating more or less (this is my interpretation) that parser1_rule have not been defined (or instantiated) for the new context trace_context_t.
Indeed, in X3, rules have two template parameters: iterators and context. I thought when mixing two rules, one had to make sure they both use the same context and iterator's types. So I paid attention to use the same context for parser1_rule and trace_parser : context_type. The same goes for the iterator, as recalled in X3: Linker Error (unresolved external symbol “parse_rule”) on nonterminal parser
But it seams this is not the way to go ? Shall I move the rule's definitions into an hpp file (which I wish I can avoid).
I created a minimal reproducible example to help understanding the issue:
EDIT: boost 1.71.0 and Visual Studio 16.8.2
unit1.h
#ifndef UNIT1_H
#define UNIT1_H
#include <cstdint>
#include "boost/spirit/home/x3.hpp"
#include "boost/spirit/include/support_istream_iterator.hpp"
namespace x3 = boost::spirit::x3;
using iter_t = boost::spirit::istream_iterator;
using context_t = x3::phrase_parse_context<x3::ascii::space_type>::type;
using parser1_t = x3::rule<class p1, std::uint64_t>;
BOOST_SPIRIT_DECLARE(parser1_t);
parser1_t const & ATparser();
#endif /* UNIT1_H */
unit1.cpp
#include "unit1.h"
parser1_t const parser1 = "parser1_rule";
auto const parser1_def = x3::lexeme[x3::lit("AT") >> x3::uint_];
BOOST_SPIRIT_DEFINE(parser1);
BOOST_SPIRIT_INSTANTIATE(parser1_t, iter_t, context_t);
parser1_t const& ATparser() { return parser1; }
Source.h
#ifndef SOURCE_H
#define SOURCE_H
#include <cstdint>
#include "boost/spirit/home/x3.hpp"
#include "boost/spirit/include/support_istream_iterator.hpp"
namespace x3 = boost::spirit::x3;
namespace trace {
using trace_parser_tag = struct trace_parser;
using rule_type = x3::rule<trace_parser_tag>;
BOOST_SPIRIT_DECLARE(rule_type);
}
trace::rule_type const& trace_parser();
#endif
Source.cpp
#include <iostream>
#include <fstream>
#include "unit1.h"
#include "Source.h"
namespace x3 = boost::spirit::x3;
/** reading:
Trace address: AT123434 */
namespace trace {
rule_type const tr = "trace_parser";
auto fill = [](auto& ctx) {}; /* semantic action to break automatic attribute propagation (first step) */
auto const tr_def = ("Trace address: " >> ATparser())[fill];
BOOST_SPIRIT_DEFINE(tr);
BOOST_SPIRIT_INSTANTIATE(rule_type,iter_t,context_t)
}
trace::rule_type const& trace_parser() {
return trace::tr;
}
int main(int argc, char* argv[])
{
std::string input("Trace address: AT123434");
std::ifstream i(input);
std::cout << "parsing: " << input << "\n";
boost::spirit::istream_iterator b(i >> std::noskipws);
boost::spirit::istream_iterator e = {};
bool v = x3::phrase_parse(b, e, trace_parser(), x3::ascii::space);
std::cout << "result: " << (v ? "OK" : "Failed") << "\n";
return v;
}
compilation output
1>Source.cpp
1>H:\X\XXXXX\unit1.h(26,1): warning C5046: 'parse_rule': Symbol involving type with internal linkage not defined
1>Source.obj : error LNK2019: unresolved external symbol "bool __cdecl parse_rule<class boost::spirit::basic_istream_iterator<char,struct std::char_traits<char> >,struct boost::spirit::x3::context<struct trace::trace_parser,struct boost::spirit::x3::action<struct boost::spirit::x3::sequence<struct boost::spirit::x3::literal_string<char const *,struct boost::spirit::char_encoding::standard,struct boost::spirit::x3::unused_type>,struct boost::spirit::x3::rule<class p1,unsigned __int64,0> >,class <lambda_bca3e58e86871d1e58f1a6062ad05fd2> > const ,struct boost::spirit::x3::context<struct boost::spirit::x3::skipper_tag,struct boost::spirit::x3::char_class<struct boost::spirit::char_encoding::ascii,struct boost::spirit::x3::space_tag> const ,struct boost::spirit::x3::unused_type> > >(struct boost::spirit::x3::rule<class p1,unsigned __int64,0>,class boost::spirit::basic_istream_iterator<char,struct std::char_traits<char> > &,class boost::spirit::basic_istream_iterator<char,struct std::char_traits<char> > const &,struct boost::spirit::x3::context<struct trace::trace_parser,struct boost::spirit::x3::action<struct boost::spirit::x3::sequence<struct boost::spirit::x3::literal_string<char const *,struct boost::spirit::char_encoding::standard,struct boost::spirit::x3::unused_type>,struct boost::spirit::x3::rule<class p1,unsigned __int64,0> >,class <lambda_bca3e58e86871d1e58f1a6062ad05fd2> > const ,struct boost::spirit::x3::context<struct boost::spirit::x3::skipper_tag,struct boost::spirit::x3::char_class<struct boost::spirit::char_encoding::ascii,struct boost::spirit::x3::space_tag> const ,struct boost::spirit::x3::unused_type> > const &,unsigned __int64 &)" [...cut...] referenced in function "public: bool __cdecl boost::spirit::x3::rule<class p1,unsigned __int64,0>::parse<class boost::spirit::basic_istream_iterator<char,struct std::char_traits<char> >,struct boost::spirit::x3::context<struct trace::trace_parser,struct boost::spirit::x3::action<struct boost::spirit::x3::sequence<struct boost::spirit::x3::literal_string<char const *,struct boost::spirit::char_encoding::standard,struct boost::spirit::x3::unused_type>,struct boost::spirit::x3::rule<class p1,unsigned __int64,0> >,class <lambda_bca3e58e86871d1e58f1a6062ad05fd2> > const ,struct boost::spirit::x3::context<struct boost::spirit::x3::skipper_tag,struct boost::spirit::x3::char_class<struct boost::spirit::char_encoding::ascii,struct boost::spirit::x3::space_tag> const ,struct boost::spirit::x3::unused_type> >,unsigned __int64>(class boost::spirit::basic_istream_iterator<char,struct std::char_traits<char> > &,class boost::spirit::basic_istream_iterator<char,struct std::char_traits<char> > const &,struct boost::spirit::x3::context<struct trace::trace_parser,struct boost::spirit::x3::action<struct boost::spirit::x3::sequence<struct boost::spirit::x3::literal_string<char const *,struct boost::spirit::char_encoding::standard,struct boost::spirit::x3::unused_type>,struct boost::spirit::x3::rule<class p1,unsigned __int64,0> >,class <lambda_bca3e58e86871d1e58f1a6062ad05fd2> > const ,struct boost::spirit::x3::context<struct boost::spirit::x3::skipper_tag,struct boost::spirit::x3::char_class<struct boost::spirit::char_encoding::ascii,struct boost::spirit::x3::space_tag> const ,struct boost::spirit::x3::unused_type> > const &,struct boost::spirit::x3::unused_type,unsigned __int64 &)const "
Warning:
1>H:\X\XXXXX\unit1.h(26,1): warning C5046: 'parse_rule': Symbol involving type with internal linkage not defined
Error message:
unresolved external symbol:
bool __cdecl parse_rule<iterator_t,trace_context_t>(
parser1_t,
iterator_t &,
iterator_t const &,
trace_context_t const &,
unsigned __int64 &
)
referenced in function
public:
bool __cdecl boost::spirit::x3::rule<class p1,unsigned __int64,0>::parse<
iterator_t, trace_context_t, unsigned __int64>
(
iterator_t &,
iterator_t const &,
trace_context_t const &,
struct boost::spirit::x3::unused_type,
unsigned __int64 &
)const
Assuming the following shorcuts:
using action_t = struct boost::spirit::x3::action<
struct boost::spirit::x3::sequence<
struct boost::spirit::x3::literal_string<
char const *,
struct boost::spirit::char_encoding::standard,
struct boost::spirit::x3::unused_type>,
struct boost::spirit::x3::rule<class p1,unsigned __int64,0>>,
class <lambda_bca3e58e86871d1e58f1a6062ad05fd2>>
using ctxt_t = struct boost::spirit::x3::context<
struct boost::spirit::x3::skipper_tag,
struct boost::spirit::x3::char_class<
struct boost::spirit::char_encoding::ascii,
struct boost::spirit::x3::space_tag> const ,
struct boost::spirit::x3::unused_type>>
using iterator_t = class boost::spirit::basic_istream_iterator<char,struct std::char_traits<char> >
using trace_context_t = struct boost::spirit::x3::context<
struct trace::trace_parser,
action_t const ,
ctxt_t>

Move to Boost 1.74.0 solved the issue.

Related

Trouble understanding static in header files ( inline )

I've been working with static for quite a long time but now when the header files come I'm a little confused.
The main problem is this code :
#include <iostream>
#include <string>
#include <sstream>
#include <set>
#ifndef WORD_H
#define WORD_H
#include<unordered_map>
class Word
{
private:
std::string word;
int k;
static std::unordered_map<std::string, int> x;
public:
Word(std::string word) : word(word)
{
if (x.find(word) != x.end())
x.insert({ word , 0 });
else
{
x[word]++;
}
}
std::string getWord() const
{
return x.find(this->word)->first;
}
int getCount() const
{
return x.find(this->word)->second;
}
friend bool operator<(const Word& a, const Word& b);
};
bool operator<(const Word& a, const Word& b)
{
return a.getWord() < b.getWord();
}
#endif
std::ostream& operator<<(std::ostream& out, const Word& w) {
return out << w.getWord() << " " << w.getCount();
}
void printWordCounts(const std::string& line) {
std::istringstream lineIn(line);
std::set<Word> words;
std::string wordStr;
while (lineIn >> wordStr) {
words.insert(Word(wordStr));
}
for (Word w : words) {
std::cout << w << std::endl;
}
}
int main() {
std::string line;
std::getline(std::cin, line);
printWordCounts(line);
std::cout << "---" << std::endl;
std::getline(std::cin, line);
printWordCounts(line);
return 0;
}
I know that there is a problem with the static keyword, but what exactly is it?
Also, the error is one of my favourites. Those errors between linker and STL:
Error LNK2001 unresolved external symbol "private: static class std::unordered_map<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,int,struct std::hash<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,struct std::equal_to<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const ,int> > > Word::x" (?x#Word##0V?$unordered_map#V?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##HU?$hash#V?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###2#U?$equal_to#V?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###2#V?$allocator#U?$pair#$$CBV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##H#std###2##std##A) ConsoleApplication63 C:\Users\Ivo\source\repos\ConsoleApplication63\ConsoleApplication63\ConsoleApplication63.obj 1
I hope that someone can give me an explanation.
You have only declared the static member x. You also need to define it outside the class like this:
std::unordered_map<std::string, int> Word::x;
From c++17, you can define x inside the class definition like this:
inline static std::unordered_map<std::string, int> x;
Static variable declarations in classes are identical to declaring a global variable in a header file, except it's 'symbol' lies within the namespace of the class and therefore access to it is protected with visibility levels. This means that like global variable declarations, static class variable declarations have 'weak' linkage and a compilation unit needs to define the symbol definition, so that the linker can tie the memory associated with the variable declarations in other files to exactly one variable.
Defining the static variable is done outside the class like so:
// <variable type> <class type>::<variable name>;
std::unordered_map<std::string, int> Word::x;
Note that only one .cpp file needs to define the variable

Linker Error - Not sure what it is not linking

I have been trying to figure out what is not linked or declared correctly in my code. I am writing a simple game engine in C++ for learning purposes and am trying to create a state machine. The linker error has something to do with unordered_list, list, or map. I am not sure which. The error is for the constructor with two arguments, which are two typedefs and is included in the code I show, the error happens when I call that constructor.
IState.h
#ifndef ZX_STATE_H
#define ZX_STATE_H
#include "coreDefines.h"
#include "zxstring.h"
ZX_NS_START
class IState
{
tstring pm_name;
public:
const tstring& name();
virtual ~IState() = default;
virtual void Pre() = 0;
virtual void Run() = 0;
virtual void Post() = 0;
};
ZX_NS_END
#endif
IStateMachine.h
#ifndef ZX_ISTATEMACHINE_H
#define ZX_ISTATEMACHINE_H
#include "object.h"
#include "zxstring.h"
#include "IState.h"
#include <unordered_set>
#include <map>
#include <list>
ZX_NS_START
typedef std::map<tstring, IState*> StateMap;
typedef std::unordered_set<tstring> StateSet;
typedef std::list<StateSet> RunOrder;
class IStateMachine : object, IState
{
public:
const tstring defaultState = T("zx default state");
IStateMachine();
IStateMachine(RunOrder** runOrder, StateSet** states);
virtual ~IStateMachine();
void Add(IState* state);
void Remove(IState* state);
private:
StateMap pm_states;
RunOrder** pm_runOrder;
StateSet** pm_activeStates;
void Pre() override;
void Run() override;
void Post() override;
void SetUpDefaultState();
class DefaultState: IState
{
IStateMachine* pm_parent;
public:
DefaultState();
explicit DefaultState(IStateMachine* parent);
void Pre() override;
void Run() override;
void Post() override;
};
};
ZX_NS_END
#endif
IStateMachine.cpp
#include "IStateMachine.h"
USINGZX;
IStateMachine::IStateMachine(): pm_states(StateMap()), pm_runOrder(nullptr), pm_activeStates(nullptr)
{
SetUpDefaultState();
}
IStateMachine::IStateMachine(RunOrder** runOrder, StateSet** states) : pm_states(StateMap()), pm_runOrder(runOrder), pm_activeStates(states)
{
SetUpDefaultState();
}
IStateMachine::~IStateMachine()
{
delete pm_states[defaultState];
}
void IStateMachine::Add(IState* state)
{
pm_states.insert(std::make_pair(state->name(), state));
}
void IStateMachine::Remove(IState* state)
{
pm_states.erase(state->name());
}
void IStateMachine::Pre()
{
pm_states[defaultState]->Pre();
}
void IStateMachine::Run()
{
pm_states[defaultState]->Run();
}
void IStateMachine::Post()
{
pm_states[defaultState]->Post();
}
void IStateMachine::SetUpDefaultState()
{
DefaultState* def = new DefaultState(this);
pm_states.insert(std::make_pair(defaultState, (IState*)def));
}
IStateMachine::DefaultState::DefaultState() :pm_parent(nullptr)
{
}
IStateMachine::DefaultState::DefaultState(IStateMachine* parent): pm_parent(parent)
{
}
void IStateMachine::DefaultState::Pre()
{
for(const auto& states : **pm_parent->pm_runOrder)
{
for(const auto& runState : states)
{
pm_parent->pm_states[runState]->Pre();
}
}
}
void IStateMachine::DefaultState::Run()
{
for(const auto& states: **pm_parent->pm_runOrder)
{
for(const auto& runState : states)
{
pm_parent->pm_states[runState]->Run();
}
}
}
void IStateMachine::DefaultState::Post()
{
for (const auto& states : **pm_parent->pm_runOrder)
{
for (const auto& runState : states)
{
pm_parent->pm_states[runState]->Post();
}
}
}
Here is the long...looong error message
Error LNK2019 unresolved external symbol "public: __thiscall Zx::IStateMachine::IStateMachine(class std::list,class std::allocator >,struct std::hash,class std::allocator > >,struct std::equal_to,class std::allocator > >,class std::allocator,class std::allocator > > >,class std::allocator,class std::allocator >,struct std::hash,class std::allocator > >,struct std::equal_to,class std::allocator > >,class std::allocator,class std::allocator > > > > > * *,class std::unordered_set,class std::allocator >,struct std::hash,class std::allocator > >,struct std::equal_to,class std::allocator > >,class std::allocator,class std::allocator > > > * *)" (??0IStateMachine#Zx##QAE#PAPAV?$list#V?$unordered_set#V?$basic_string#_WU?$char_traits#_W#std##V?$allocator#_W#2##std##U?$hash#V?$basic_string#_WU?$char_traits#_W#std##V?$allocator#_W#2##std###2#U?$equal_to#V?$basic_string#_WU?$char_traits#_W#std##V?$allocator#_W#2##std###2#V?$allocator#V?$basic_string#_WU?$char_traits#_W#std##V?$allocator#_W#2##std###2##std##V?$allocator#V?$unordered_set#V?$basic_string#_WU?$char_traits#_W#std##V?$allocator#_W#2##std##U?$hash#V?$basic_string#_WU?$char_traits#_W#std##V?$allocator#_W#2##std###2#U?$equal_to#V?$basic_string#_WU?$char_traits#_W#std##V?$allocator#_W#2##std###2#V?$allocator#V?$basic_string#_WU?$char_traits#_W#std##V?$allocator#_W#2##std###2##std###2##std##PAPAV?$unordered_set#V?$basic_string#_WU?$char_traits#_W#std##V?$allocator#_W#2##std##U?$hash#V?$basic_string#_WU?$char_traits#_W#std##V?$allocator#_W#2##std###2#U?$equal_to#V?$basic_string#_WU?$char_traits#_W#std##V?$allocator#_W#2##std###2#V?$allocator#V?$basic_string#_WU?$char_traits#_W#std##V?$allocator#_W#2##std###2##3##Z) referenced in function "public: __thiscall TestStateMachine::TestStateMachine(class std::list,class std::allocator >,struct std::hash,class std::allocator > >,struct std::equal_to,class std::allocator > >,class std::allocator,class std::allocator > > >,class std::allocator,class std::allocator >,struct std::hash,class std::allocator > >,struct std::equal_to,class std::allocator > >,class std::allocator,class std::allocator > > > > > * *,class std::unordered_set,class std::allocator >,struct std::hash,class std::allocator > >,struct std::equal_to,class std::allocator > >,class std::allocator,class std::allocator > > > * *)" (??0TestStateMachine##QAE#PAPAV?$list#V?$unordered_set#V?$basic_string#_WU?$char_traits#_W#std##V?$allocator#_W#2##std##U?$hash#V?$basic_string#_WU?$char_traits#_W#std##V?$allocator#_W#2##std###2#U?$equal_to#V?$basic_string#_WU?$char_traits#_W#std##V?$allocator#_W#2##std###2#V?$allocator#V?$basic_string#_WU?$char_traits#_W#std##V?$allocator#_W#2##std###2##std##V?$allocator#V?$unordered_set#V?$basic_string#_WU?$char_traits#_W#std##V?$allocator#_W#2##std##U?$hash#V?$basic_string#_WU?$char_traits#_W#std##V?$allocator#_W#2##std###2#U?$equal_to#V?$basic_string#_WU?$char_traits#_W#std##V?$allocator#_W#2##std###2#V?$allocator#V?$basic_string#_WU?$char_traits#_W#std##V?$allocator#_W#2##std###2##std###2##std##PAPAV?$unordered_set#V?$basic_string#_WU?$char_traits#_W#std##V?$allocator#_W#2##std##U?$hash#V?$basic_string#_WU?$char_traits#_W#std##V?$allocator#_W#2##std###2#U?$equal_to#V?$basic_string#_WU?$char_traits#_W#std##V?$allocator#_W#2##std###2#V?$allocator#V?$basic_string#_WU?$char_traits#_W#std##V?$allocator#_W#2##std###2##2##Z)
I can usually figure these out pretty easily but for what ever reason this one is stumping me.(Maybe something to do with the unreadable type in the error message)
I don't believe this will be of any consequence, however, here is the test code that invokes the linker error
StateMachineTest.cpp
class TestStateMachine : zx IStateMachine
{
public:
TestStateMachine(zx RunOrder** order, zx StateSet** active) : zx IStateMachine(order, active)
{
}
};
TEST_CLASS(StateMachineTest)
{
public:
TEST_METHOD(IStateMachineTest)
{
auto* order = new zx RunOrder();
auto* active = new zx StateSet();
TestStateMachine test = TestStateMachine(&order, &active);
}
};
I removed all your macro stuff, and #includes with missing header files, provided a replacement for tstring like typedef std::basic_string<TCHAR> tstring; and an implementation for const tstring& IState::name() { return pm_name; } and the code compiles without error.
Assuming that USINGZX is using namespace zx; then this code does not define IStateMachine::IStateMachine in the zx namespace, it's in the global namespace.
USINGZX;
IStateMachine::IStateMachine(): pm_states(StateMap()), pm_runOrder(nullptr), pm_activeStates(nullptr)
{
SetUpDefaultState();
}
If you want to define IStateMachine::IStateMachine in the zx namespace then you've either got to say
zx::IStateMachine::IStateMachine(): pm_states(StateMap()), pm_runOrder(nullptr), pm_activeStates(nullptr)
{
SetUpDefaultState();
}
or
namespace zx {
IStateMachine::IStateMachine(): pm_states(StateMap()), pm_runOrder(nullptr), pm_activeStates(nullptr)
{
SetUpDefaultState();
}
}

Unable to link Boost libs to vs2010

I know this question has been asked a lot of times here. But after trying all the mentioned solutions I am still not able to Compile the Test Boost code.
I have followed the following Steps for installation :-
Unzip Boost into a new directory.
Start a 64-bit MSVC command prompt and change to the directory where Boost was unzipped.
Run: bootstrap
Run: b2 toolset=msvc-10.0 --build-type=complete --libdir=C:\Boost\lib\x64 architecture=x86 address-model=64 install
Add C:\Boost\include\boost-(version) to your include path in Microsoft.Cpp.Win32.user property sheets.
Add C:\Boost\lib\x64 to your libs path in Microsoft.Cpp.Win32.user property sheets.
Additionally, I have added the lib path in additional library directory.
I am trying to compile a standard code to test whether boost is working properly or not.
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/regex.hpp>
using namespace std;
struct Hello
{
Hello(){
cout << "Hello constructor" << endl;
}
~Hello(){
cout << "Hello destructor" << endl;
cin.get();
}
};
int main(int argc, char**argv)
{
//Boost regex, compiled library
boost::regex regex("^(Hello|Bye) Boost$");
boost::cmatch helloMatches;
boost::regex_search("Hello Boost", helloMatches, regex);
cout << "The word between () is: " << helloMatches[1] << endl;
//Boost shared pointer, header only library
boost::shared_ptr<Hello> sharedHello(new Hello);
return 0;
}
The linker error I am getting is:-
1>Sample.obj : error LNK2019: unresolved external symbol "private: class boost::basic_regex<char,struct boost::regex_traits<char,class boost::w32_regex_traits<char> > > & __thiscall boost::basic_regex<char,struct boost::regex_traits<char,class boost::w32_regex_traits<char> > >::do_assign(char const *,char const *,unsigned int)" (?do_assign#?$basic_regex#DU?$regex_traits#DV?$w32_regex_traits#D#boost###boost###boost##AAEAAV12#PBD0I#Z) referenced in function "public: class boost::basic_regex<char,struct boost::regex_traits<char,class boost::w32_regex_traits<char> > > & __thiscall boost::basic_regex<char,struct boost::regex_traits<char,class boost::w32_regex_traits<char> > >::assign(char const *,char const *,unsigned int)" (?assign#?$basic_regex#DU?$regex_traits#DV?$w32_regex_traits#D#boost###boost###boost##QAEAAV12#PBD0I#Z)
1>Sample.obj : error LNK2019: unresolved external symbol "public: bool __thiscall boost::re_detail::perl_matcher<char const *,class std::allocator<struct boost::sub_match<char const *> >,struct boost::regex_traits<char,class boost::w32_regex_traits<char> > >::find(void)" (?find#?$perl_matcher#PBDV?$allocator#U?$sub_match#PBD#boost###std##U?$regex_traits#DV?$w32_regex_traits#D#boost###boost###re_detail#boost##QAE_NXZ) referenced in function "bool __cdecl boost::regex_search<char const *,class std::allocator<struct boost::sub_match<char const *> >,char,struct boost::regex_traits<char,class boost::w32_regex_traits<char> > >(char const *,char const *,class boost::match_results<char const *,class std::allocator<struct boost::sub_match<char const *> > > &,class boost::basic_regex<char,struct boost::regex_traits<char,class boost::w32_regex_traits<char> > > const &,enum boost::regex_constants::_match_flags,char const *)" (??$regex_search#PBDV?$allocator#U?$sub_match#PBD#boost###std##DU?$regex_traits#DV?$w32_regex_traits#D#boost###boost###boost##YA_NPBD0AAV?$match_results#PBDV?$allocator#U?$sub_match#PBD#boost###std###0#ABV?$basic_regex#DU?$regex_traits#DV?$w32_regex_traits#D#boost###boost###0#W4_match_flags#regex_constants#0#0#Z)
1>Sample.obj : error LNK2019: unresolved external symbol "private: void __thiscall boost::re_detail::perl_matcher<char const *,class std::allocator<struct boost::sub_match<char const *> >,struct boost::regex_traits<char,class boost::w32_regex_traits<char> > >::construct_init(class boost::basic_regex<char,struct boost::regex_traits<char,class boost::w32_regex_traits<char> > > const &,enum boost::regex_constants::_match_flags)" (?construct_init#?$perl_matcher#PBDV?$allocator#U?$sub_match#PBD#boost###std##U?$regex_traits#DV?$w32_regex_traits#D#boost###boost###re_detail#boost##AAEXABV?$basic_regex#DU?$regex_traits#DV?$w32_regex_traits#D#boost###boost###3#W4_match_flags#regex_constants#3##Z) referenced in function "public: __thiscall boost::re_detail::perl_matcher<char const *,class std::allocator<struct boost::sub_match<char const *> >,struct boost::regex_traits<char,class boost::w32_regex_traits<char> > >::perl_matcher<char const *,class std::allocator<struct boost::sub_match<char const *> >,struct boost::regex_traits<char,class boost::w32_regex_traits<char> > >(char const *,char const *,class boost::match_results<char const *,class std::allocator<struct boost::sub_match<char const *> > > &,class boost::basic_regex<char,struct boost::regex_traits<char,class boost::w32_regex_traits<char> > > const &,enum boost::regex_constants::_match_flags,char const *)" (??0?$perl_matcher#PBDV?$allocator#U?$sub_match#PBD#boost###std##U?$regex_traits#DV?$w32_regex_traits#D#boost###boost###re_detail#boost##QAE#PBD0AAV?$match_results#PBDV?$allocator#U?$sub_match#PBD#boost###std###2#ABV?$basic_regex#DU?$regex_traits#DV?$w32_regex_traits#D#boost###boost###2#W4_match_flags#regex_constants#2#0#Z)
1>C:\Users\J.A.R.V.I.S\documents\visual studio 2010\Projects\Boost Sample\Debug\Boost Sample.exe : fatal error LNK1120: 3 unresolved externals
1>
What am I missing here?
I am using VS2010 and windows 64bit.
Thanks
There were 2 issues which were giving the linker error:-
Additional linker dependencies absent at Properties->Linker->Input->AdditionalDependencies
Project was win32. Needed to convert it to x64 using configuration manager.

C++ Unresolved symbol

I just don't see where I went wrong.
The compiler complains about
Error 215 error LNK2001: Unresolved external symbol ""class std::vector<class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> >,class std::allocator<class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > > > __cdecl splitW(class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > &,class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > const &)" (?splitW##YA?AV?$vector#V?$basic_string#_WU?$char_traits#_W#std##V?$allocator#_W#2##std##V?$allocator#V?$basic_string#_WU?$char_traits#_W#std##V?$allocator#_W#2##std###2##std##AAV?$basic_string#_WU?$char_traits#_W#std##V?$allocator#_W#2##2#ABV32##Z)". C:\voice\clsText.obj voice
But I don't see where I went wrong. Can somebody tell me how to analyze this error message? I get it quite often, but then again I never remember how I solved it.
Thank you very much!
This is my code in strhelper.cpp:
vector<wstring> splitW(const wstring& uMain, const wstring &uSplitBy)
{
vector<wstring>s;
int iStart=0;
for (;;)
{
int iPos=uMain.find(uSplitBy,iStart);
if (iPos==-1)
{
wstring s1;
s1 = uMain.substr(iStart,uMain.size() - iStart);
if (s1.size()>0)
{
s.push_back(s1);
}
break;
}
else
{
wstring s2;
s2 = uMain.substr(iStart,iPos-iStart);
s.push_back(s2);
iStart = iPos + 1;
}
}
return s;
}
And this is the part of the header that contains the declaration:
void replaceOnce(wstring& uText,const wstring& uSearchFor,const wstring& uReplaceWith,bool uTextCompare);
vector<wstring> splitW(wstring &str, const wstring &uSep);
vector<wstring> splitAToWVec(const string& uMain, const string& uSplitBy);
vector<string> splitAToAVec(const string& uMain, const string& uSplitBy);
The type of the 1st parameter of splitW() is declared as wstring& in header file but defined as const wstring& in source code. Please make them consistent.
Declaration:
vector<wstring> splitW( wstring& str, const wstring &uSep);
Definition:
vector<wstring> splitW(const wstring& uMain, const wstring &uSplitBy)

LNK2019 error while using IBPP in Firebreath project

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