之前發現直接編譯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 中國大陸許可協議進行許可。