2010年12月10日 星期五

boost 1.38更新到1.45 記錄

今天更新了工作用的boost 1.38,之前也是一直想更新,可是都沒空閒,或是怎麼一更新complier就一堆錯誤。
所以剛好今天有空,而且也快年底了,就趕快更新一下,底下列出我更新時遇到的問題。

1. exception header file改變

#include <boost/exception.hpp>

改為

#include <boost/exception/all.hpp>


心得: 不知道這樣改的原因是為什麼,原本不是好好的嗎

2. boost::exception的 get_error_info介面改變

我自己做的logger library會手動去讀取boost::exception的error info
原本是像底下這樣

boost::shared_ptr<char const * const> f = boost::get_error_info<boost::throw_file>(ex)

改成

const boost::throw_file::value_type* f = boost::get_error_info<boost::throw_file>(ex)


3. binary archive bug

之前的boost 1.38版本的binary_iarchive是version 5的,現在到boost 1.45該class也更新到version 8
更新是沒什麼關係,只要有相容舊版的就好,悲劇的就是他不相容... T____T
想一想,這種大型又多人使用的library,在檔案處理上不相容舊版,怎麼想都沒道理啊
於是我就去trace底層的程式碼,並且和boost 1.38版的程式對照,終於讓我發現bug了


開啟boost/archive/basic_binary_iarchive.hpp並找到

void load_override(version_type & t, int version){
library_version_type lvt = this->get_library_version();
if(boost::archive::library_version_type(7) < lvt){
this->detail_common_iarchive::load_override(t, version);
}
else
if(boost::archive::library_version_type(6) < lvt){
uint_least16_t x=0;
* this->This() >> x;
t = boost::archive::version_type(x);
}
else{
unsigned int x=0;
* this->This() >> x;
t = boost::archive::version_type(x);
}
}

可以發現到,若目前lvt是5的話會執行else那段程序,x 的宣告是unsigned int

我們再看一下boost 1.38的該段程式碼

void load_override(version_type & t, int){
// upto 255 versions
unsigned char x=0;
* this->This() >> x;
t = version_type(x);
}

Oops!!! 同樣是x,可是size不一樣...

有問題的還包括 void load_override(class_id_type & t, int version) 這個function
不知道boost 的issue tracking有沒有登錄這個bug了

4. boost::thread + MFC DLL 問題

基本上這個問題在boost 1.38就有了,但是原因有點年代久遠我也忘光光了... 囧
只是沒想到更新成boost 1.45後問題還是沒有解決...

如果你是使用MFC開發程式 ,又剛好你建立的MFC DLL檔有使用boost::thread,就會發生compile正常但是一執行程式出現ASSERT。

解決方法就是到boost/libs/thread/src/win32/tss_pe.cpp裡
把底下的程式碼註解掉
extern BOOL (WINAPI * const _pRawDllMain)(HANDLE, DWORD, LPVOID)=&dll_callback;

再重新compile boost問題就解決了









2010年6月4日 星期五

boost::archive::xml_oarchive 遇上unicode的assert


#include <boost/xml_oarchive.hpp>
#include <sstream>
#include <string>

int _tmain(int argc, _TCHAR* argv[])
{
std::stringstream ss;

boost::archive::xml_oarchive ar(ss);
const std::wstring str = L"測試";
ar & boost::serialization::make_nvp("str", str);

return 0;
}


上面這一段程式碼,在debug模式下會出現assert。
這時候將str稍微改一下就正常了。


#include <boost/xml_oarchive.hpp>
#include <sstream>
#include <string>

int _tmain(int argc, _TCHAR* argv[])
{
std::stringstream ss;

boost::archive::xml_oarchive ar(ss);
const std::wstring str = L"ABC";
ar & boost::serialization::make_nvp("str", str);

return 0;
}


主要原因是因為locale的關係,在xml_oarchive寫入資料時會透過wctomb將unicode轉成multibyte,此時因為locale不對造成轉換錯誤,而產生assert。
所以只要在使用xml archive前先setlocale就ok了。


#include <boost/xml_oarchive.hpp>
#include <boost/xml_iarchive.hpp>
#include <sstream>
#include <string>
#include <assert>

int _tmain(int argc, _TCHAR* argv[])
{
std::stringstream ss;

{
boost::archive::xml_oarchive ar(ss);
const std::wstring str = L"測試";
ar & boost::serialization::make_nvp("str", str);
}

{
boost::archive::xml_iarchive ar(ss);
std::wstring str;
ar & boost::serialization::make_nvp("str", str);
assert(str == L"測試");
}

return 0;
}


不過,比較好的做法是存檔時先將wchar_t轉成utf-8再交給xml archive,讀檔時再把utf-8轉成wchar_t

2010年3月18日 星期四

namespace 的分類設計

最近習慣為每個模組加上namespace,享受namespace帶來的設計概念,但是也遇到了namespace的分類問題,常常namespace分得不夠好且使用起來也不方便,主要是我對於我的code的模組有時候分得不夠清楚,都是是在錯誤中學習,將1個模組拆成2個又將2個合併為1個,花了很多時間在這方面... 囧

後來大概上網看了一下,一直在想boost::tuple的命名概念,我想我以後再設計namespace時就按照這個一般的原則執行就好了。
The common principle is that domain libraries (like graph, python) should be on a separate subnamespace, while utility like libraries directly in the boost namespace.
文章中也有提到tuple設計的結果
The final (I truly hope so) solution is now to have all definitions in namespace ::boost::tuples, and the most common names in the ::boost namespace as well. This is accomplished with using declarations (suggested by Dave Abrahams):
namespace boost {
namespace tuples {
...
// All library code
...
}
using tuples::tuple;
using tuples::make_tuple;
using tuples::tie;
using tuples::get;
}

2010年3月17日 星期三

今天你不操死他們,有一天你就會被他們操死! 囧

我在管理工作上,一直都做得不是很好,想了一想大概是底下幾個問題
  1. 時間管理不好,因為自己還是要寫code,專心的時候就不想要去處理別人的問題,導致即使自己的code有準時完成,但是多數人卻因為問題delay了,整個部分的績效及產品的研發速度很差。
  2. 好好先生,我可能想要去當每個人的好朋友,或是不想要給每個人太大壓力,導致最後累的是自己,也許有一天自己也不想給自己壓力了吧。今天你不操死他們,有一天你就會被他們操死!
好吧,加油吧,別人的問題優先處理,寧願當個壞人也不要當個讓部門擺爛的好人。
基本上我只是很小很小咖的角色,我是非常希望我頭頭也有這種體會,讓整個研發團隊更厲害。

------

囧,上一篇blog文章是去年的這個時候了,我實在有夠懶...

LinkWithin

Related Posts with Thumbnails