OS环境:
Centos 7.1 release
X86_64
编译环境:
G++ 4.8.3
已经成功搭建好了Mongodb,也初步在命令行中的查询与写入数据的基本方法,现在通过C++来连接Mongodb。
1.准备工作
(1).在官网中下载mongodb的C++ driver
官方文档说明:
https://github.com/mongodb/mongo-cxx-driver/wiki/Download-and-Compile-the-Legacy-Driver
值得注意的是,上方文档说明中的git仓库已经不可用,在github中可以搜索到,使用如下地址
https://github.com/mongodb/mongo-cxx-driver.git
clone下来:
git clone https://github.com/mongodb/mongo-cxx-driver.git
(2).安装构建工具
mongodb 使用scons工具来自动化构建mongodb driver for c++, 而我centos上没有预装这个工具,为了节省时间,我直接使用yum来安装
yum install scons。
(3).安装Mongodb驱动 / mongodb-c++开发中所必需的库。这就是复杂但是好用,庞大但是很富有精华的强大的Boost库。
为了节省时间,我也选用的是二进制包来安装,需要的话也可以选择源码编译。
yum install boost-devel
安装完成之后,当前在我的Centos上,头文件存在于/usr/include/boost , 动态库文件存在与/usr/lib64/ 下.
安装Boost库也是编译C++ mongodb驱动的必要步骤.
2.开始编译driver
(1).编译mongodb-cxx-driver
在上述准备工作都已做好的时候,就可以来编译驱动了。
cd mongo-cxx-driver , 直接 scons 命令,就开始自动编译构建驱动 [ 需要更改安装路径的可以选择 –prefix=$HOME/local/mongo ]选项,在编译的时候若系统中没有存在Boost开发库的话,会报错,提示需要安装boost开发库,若需要请先看第三步。确认无误之后,编译完成会构建出build目录,目录结构:
|-build
|—–install
|———-include
|———-lib
|—–linux2
|—–scons
在这里,我们需要的是install/include 与 install/lib文件。而且lib下只有一个库文件libmongodbclient.a
cd build
cp include ~/local/include
cp lib ~/local/lib
复制到我们常用开发的头文件与库文件目录中。
我在编译的时候没有遇到过报错。这样,驱动已成功编译完成
3.使用C++来连接Mongodb
/** * Mongodb connect for c++ * author kk * 2015/06/17 */ #include <iostream> #include "mongo/client/dbclient.h" using namespace mongo; using namespace std; void run(){ DBClientConnection c; c.connect("localhost"); } int main(){ try{ run(); cout<<"connect ok"<<endl; }catch(DBException &e){ cout<<"caught"<<e.what()<<endl; } return 0; }
单个文件就不使用makefile了,输入命令
g++ main.cpp -I ~/local/include/ ~/local/lib/libmongoclient.a -lboost_thread-mt -lboost_filesystem -lboost_program_options
在大多数教程中会提醒你这么来编译你的源代码,但是,这样会报错,详见错误
/home/kangkai/local/lib/libmongoclient.a(dbclient.o): In function `boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::assign(char const*, char const*, unsigned int)’:
/usr/include/boost/regex/v4/basic_regex.hpp:382: undefined reference to `boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::do_assign(char const*, char const*, unsigned int)’
/home/kangkai/local/lib/libmongoclient.a(dbclient.o): In function `boost::re_detail::perl_matcher<__gnu_cxx::__normal_iterator<char const*, std::string>, std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<char const*, std::string> > >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::unwind_extra_block(bool)’:
/usr/include/boost/regex/v4/perl_matcher_non_recursive.hpp:1117: undefined reference to `boost::re_detail::put_mem_block(void*)’
/home/kangkai/local/lib/libmongoclient.a(dbclient.o): In function `boost::re_detail::cpp_regex_traits_implementation<char>::error_string(boost::regex_constants::error_type) const’:
/usr/include/boost/regex/v4/cpp_regex_traits.hpp:447: undefined reference to `boost::re_detail::get_default_error_string(boost::regex_constants::error_type)’
/home/kangkai/local/lib/libmongoclient.a(dbclient.o): In function `void boost::re_detail::raise_error<boost::regex_traits_wrapper<boost::regex_traits<char, boost::cpp_regex_traits<char> > > >(boost::regex_traits_wrapper<boost::regex_traits<char, boost::cpp_regex_traits<char> > > const&, boost::regex_constants::error_type)’:
/usr/include/boost/regex/pattern_except.hpp:75: undefined reference to `boost::re_detail::raise_runtime_error(std::runtime_error const&)’
/home/kangkai/local/lib/libmongoclient.a(dbclient.o): In function `boost::re_detail::cpp_regex_traits_implementation<char>::error_string(boost::regex_constants::error_type) const’:
/usr/include/boost/regex/v4/cpp_regex_traits.hpp:445: undefined reference to `boost::re_detail::get_default_error_string(boost::regex_constants::error_type)’
/home/kangkai/local/lib/libmongoclient.a(dbclient.o): In function `boost::cpp_regex_traits<char>::transform_primary(char const*, char const*) const’:
/usr/include/boost/regex/v4/cpp_regex_traits.hpp:923: undefined reference to `boost::re_detail::cpp_regex_traits_implementation<char>::transform_primary(char const*, char const*) const’
/home/kangkai/local/lib/libmongoclient.a(dbclient.o): In function `boost::cpp_regex_traits<char>::transform(char const*, char const*) const’:
/usr/include/boost/regex/v4/cpp_regex_traits.hpp:919: undefined reference to `boost::re_detail::cpp_regex_traits_implementation<char>::transform(char const*, char const*) const’
/home/kangkai/local/lib/libmongoclient.a(dbclient.o): In function `boost::re_detail::perl_matcher<__gnu_cxx::__normal_iterator<char const*, std::string>, std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<char const*, std::string> > >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::extend_stack()’:
/usr/include/boost/regex/v4/perl_matcher_non_recursive.hpp:213: undefined reference to `boost::re_detail::get_mem_block()’
/home/kangkai/local/lib/libmongoclient.a(dbclient.o): In function `save_state_init’:
/usr/include/boost/regex/v4/perl_matcher_non_recursive.hpp:107: undefined reference to `boost::re_detail::get_mem_block()’
/home/kangkai/local/lib/libmongoclient.a(dbclient.o): In function `boost::re_detail::perl_matcher<__gnu_cxx::__normal_iterator<char const*, std::string>, std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<char const*, std::string> > >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::match_imp()’:
/usr/include/boost/regex/v4/perl_matcher_common.hpp:206: undefined reference to `boost::re_detail::verify_options(unsigned int, boost::regex_constants::_match_flags)’
/home/kangkai/local/lib/libmongoclient.a(dbclient.o): In function `~save_state_init’:
/usr/include/boost/regex/v4/perl_matcher_non_recursive.hpp:115: undefined reference to `boost::re_detail::put_mem_block(void*)’
/usr/include/boost/regex/v4/perl_matcher_non_recursive.hpp:115: undefined reference to `boost::re_detail::put_mem_block(void*)’
/home/kangkai/local/lib/libmongoclient.a(dbclient.o): In function `perl_matcher’:
/usr/include/boost/regex/v4/perl_matcher.hpp:374: undefined reference to `boost::re_detail::perl_matcher<__gnu_cxx::__normal_iterator<char const*, std::string>, std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<char const*, std::string> > >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::construct_init(boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > > const&, boost::regex_constants::_match_flags)’
/home/kangkai/local/lib/libmongoclient.a(dbclient.o): In function `boost::re_detail::perl_matcher<__gnu_cxx::__normal_iterator<char const*, std::string>, std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<char const*, std::string> > >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::match_match()’:
/usr/include/boost/regex/v4/perl_matcher_non_recursive.hpp:973: undefined reference to `boost::match_results<__gnu_cxx::__normal_iterator<char const*, std::string>, std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<char const*, std::string> > > >::maybe_assign(boost::match_results<__gnu_cxx::__normal_iterator<char const*, std::string>, std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<char const*, std::string> > > > const&)’
collect2: error: ld returned 1 exit status
对于向来喜欢编译来安装的我来说,这样的错误实在郁闷了一阵。导致这样的原因无非就是动态库链接错误,找不到声明与符号。根据提示,只需在编译时加上动态库就好了。
g++ main.cpp -I ~/local/include/ ~/local/lib/libmongoclient.a /usr/lib64/libboost_regex-mt.so -lboost_thread-mt -lboost_filesystem -lboost_program_options
OK,无输出即便就是正确。
./a.out
connect ok
4.结尾
到这里,C++连接Mongodb已经成功,只是需要Boost库略显庞大。