• Mongodb Compile C++ Driver


    之前发现直接编译mongo源码中的驱动,静态库的驱动会很大,在链接使用的时候会报很多链接错误。

    转而直接编译单独提供驱动源码,同样vc2008的版本也要做我的另一篇博文中修改,在这不多说,具体参见:

    http://www.cnblogs.com/tangdoudou/p/3364015.html

    1.首先说明一点,这边是编译的vc2008的版本,因为Mongo现在提供代码只有vs2010的工程,代码里面有C11的东东,故直接移植到vs2008上是不行的,如果是编译2010请跳过。

    在做命令行执行任何命令之前,请执行vcvars32.bat,这个文件在你的vs2008的sdk目录下面。切忌!

    2.下载2.4.6的Mongodb C++ Driver

    3.按照http://www.cnblogs.com/tangdoudou/p/3364015.html中对驱动做适应性的修改,主要修改为C11和WIN32的问题。

    4.编译boost(1.4.90),我编译的release版本,debug版本在链接的时候会报错:

    Building Yourself
    
    Download the boost source from boost.org. Move it to C:\boost\.
    From the Visual Studio 2008 IDE, choose Tools.Visual Studio Command Prompt to get a command prompt with all PATH variables set nicely for the C++ compiler.
    From the MongoDB source project, run buildscripts\buildboost.bat. Or, buildboost64.bat for the 64 bit version.
    When using bjam, MongoDB expects
    
    variant=debug for debug builds, and variant=release for release builds
    threading=multi
    link=static runtime-link=static for release builds
    address-model=64 for 64 bit

    编译报错:

    libcmt.lib(invarg.obj) : error LNK2005: __initp_misc_invarg 已经在 LIBCMTD.lib(invarg.obj) 中定义
    1>libcmt.lib(invarg.obj) : error LNK2005: __invoke_watson 已经在 LIBCMTD.lib(invarg.obj) 中定义
    1>libcmt.lib(invarg.obj) : error LNK2005: __set_invalid_parameter_handler 已经在 LIBCMTD.lib(invarg.obj) 中定义
    1>libcmt.lib(invarg.obj) : error LNK2005: __get_invalid_parameter_handler 已经在 LIBCMTD.lib(invarg.obj) 中定义
    1>libcmt.lib(invarg.obj) : error LNK2005: "void __cdecl _invoke_watson(unsigned short const *,unsigned short const *,unsigned short const *,unsigned int,unsigned int)" (?_invoke_watson@@YAXPBG00II@Z) 已经在 LIBCMTD.lib(invarg.obj) 中定义
    1>libcmt.lib(invarg.obj) : error LNK2005: __invalid_parameter 已经在 LIBCMTD.lib(invarg.obj) 中定义
    1>libcmt.lib(invarg.obj) : error LNK2005: "void __cdecl _invalid_parameter(unsigned short const *,unsigned short const *,unsigned short const *,unsigned int,unsigned int)" (?_invalid_parameter@@YAXPBG00II@Z) 已经在 LIBCMTD.lib(invarg.obj) 中定义
    1>libcmt.lib(invarg.obj) : error LNK2005: ___pInvalidArgHandler 已经在 LIBCMTD.lib(invarg.obj) 中定义
    1>libcpmtd.lib(xdebug.obj) : warning LNK4098: 默认库“libcmt.lib”与其他库的使用冲突;请使用 /NODEFAULTLIB:library

    这个运行CLR差别导致的错误,我暂时也没办法解决,后面如果搞定了,在补上来。有答案的兄弟,看见了也请知会一声,谢谢。

    在CMD或者PowerShell中执行:

    1 ./bjam stage variant=release  --with-filesystem --with-thread --with-date_time --with-program_options --layout=versioned threading=multi toolset=msvc-9.0 --build-type=complete link=static runtime-link=static

    如果不出意外的话,编译后boost/stage/lib文件夹下生产5个dll和15个lib文件。

    3.打开驱动根目录下面的SConstruct文件,在行尾添加:

    1 env.Append(CPPPATH=["D:/mongodb/boost_1_49_0"], LIBPATH=["D:/mongodb/boost_1_49_0/stage/lib"])

    具体路径请替换为你的路径

    4.编译Mongodb Compile C++ Driver

    直接敲:scons

    不出意外的还是会有编译错误:(下面摘自:http://blog.csdn.net/kuaile123/article/details/9963925

    提示text.h(89):#error temp error

    这是因为scons没带使用 Unicode 字符集的参数,于是就默认使用多字节字符集

    我们打开\mongo-cxx-driver-v2.2\src\mongo\util下的text.h文件

    1 /* like toWideString but UNICODE macro sensitive */
    2 # if !defined(_UNICODE)
    3 #error temp error 
    4     inline std::string toNativeString(const char *s) { return s; }
    5 # else
    6     inline std::wstring toNativeString(const char *s) { return toWideString(s); }
    7 # endif

    将#error temp error加双斜线注释掉 //#error temp error,其实这么改不是很好,看后面你就会知道。

    可是输入后出错:

    这些无法解析的外部符号包含在WS2_32.lib,Dbghelp.lib中,在SConstruct文件中加入

    1 env.Append(LIBS=['WS2_32','Dbghelp'])

    注:我直接SConstruct加上面这一行代码,并没有解决问题,反而在我的客户端程序中增加:

    1 #include "mongo/client/dbclient.h"
    2 #pragma  comment(lib, "mongoclient.lib")
    3 #pragma comment(lib, "wsock32.lib")
    4 #pragma comment(lib, "Dbghelp.lib")

    倒是解决这个问题了

    5.如果你也遇到“\mongo-cxx-driver-v2.4\src\mongo\util”中file.cpp文件中90行

    1          _handle = CreateFileW(toNativeString(filename).c_str(),  

    报的字符编码问题,请将CreateFileW函数修改为多字节编码的函数:CreateFile,当然最好是加宏隔断控制下:

     1         #ifdef _UNICODE //edit by tangpengchuan
     2          _handle = CreateFileW(toNativeString(filename).c_str(),                 // filename
     3                               (readOnly ? 0 : GENERIC_WRITE) | GENERIC_READ,    // desired access
     4                               FILE_SHARE_WRITE | FILE_SHARE_READ,               // share mode
     5                               NULL,                                             // security
     6                               OPEN_ALWAYS,                                      // create or open
     7                               FILE_ATTRIBUTE_NORMAL,                            // file attributes
     8                               NULL);                                            // template
     9         else
    10          _handle = CreateFile(toNativeString(filename).c_str(),                 // filename
    11                               (readOnly ? 0 : GENERIC_WRITE) | GENERIC_READ,    // desired access
    12                               FILE_SHARE_WRITE | FILE_SHARE_READ,               // share mode
    13                               NULL,                                             // security
    14                               OPEN_ALWAYS,                                      // create or open
    15                               FILE_ATTRIBUTE_NORMAL,                            // file attributes
    16                               NULL);                                            // template
    17         #endif
    18         // end by tangpengchuan

    我个人觉得这么改很弱智,后面再改了

    6.把编译好的release版本的boost和Mongodb Compile C++ Driver链接到你的Client工程里面,记得要把运行时库改为MT!

    附上测试驱动Demo:

     1 #include "mongo/client/dbclient.h"
     2 #pragma  comment(lib, "mongoclient.lib")
     3 #pragma comment(lib, "wsock32.lib")
     4 #pragma comment(lib, "Dbghelp.lib")
     5 using namespace mongo;
     6 int main()
     7 {    
     8     std::string err;
     9     mongo::DBClientConnection conn;
    10     if (!conn.connect(std::string("172.17.182.86:27017"),err))
    11     {
    12         std::cout << "cannot connect db:"<< err << std::endl;
    13     }
    14     else
    15     {
    16         std::cout << "connect db:"<< err << std::endl;
    17     }
    18     std::system("pause");
    19     return 0;
    20 }

    测试通过

    如果你还有什么别的问题,欢迎来信交流。

    知识共享许可协议
    本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

  • 相关阅读:
    数组中的逆序对 --剑指offer
    第一个只出现一次的字符 --剑指offer
    丑数 --剑指offer
    把数组排成最小的数 --剑指offer
    整数中1出现的次数 --剑指offer
    最小的k个数 --剑指offer
    数组中出现次数超过一半的数字 --剑指offer
    redis击穿,穿透,雪崩,分布式锁,api(jedis,luttuce)
    Java创建数据库新建表及初始化表
    generatorConfig.xml自动生成实体类,dao和xml
  • 原文地址:https://www.cnblogs.com/tangdoudou/p/3366033.html
Copyright © 2020-2023  润新知