Thursday, March 15, 2007

模版分离重载

用Boost::bind可以实现很多匪夷所思的绑定,比如将不同类型的参数绑定到一个函数上。在SAGE的回调函数中,希望能提供一个尽量统一的接口,使得用户可以使用function/member function来作为回调函数,回调函数的参数可以是各种类型,SAGE 将自动从输入流中读取该类型的数据并传回给回调函数。
本来想用function1来包装回调函数,以为可以轻松搞定。结果发现当T=void时,不能定义void类型的变量并作为形参……编译出错
苦思冥想了半天,终于用bind绑定函数,然后将bind的返回对象bind_t进行分离重载,重载成L=boost::_bi::list0和list1两个函数,终于搞定。
然后想用同样的方法bind绑定member function,再分离重载……谁又知member function(void)和function(T)都是L=boost::_bi::list1这样的形式……然后再苦思冥想分离……
最后:
void BindedCall( boost::_bi::bind_t〈R, F, boost::_bi::list0〉 Func ) // function(void), 不读入
void BindedCall( boost::_bi::bind_t〈R, F, boost::_bi::list1〈boost::arg〈1〉〉〉 Func ) // function(T), 读入
void BindedCall( boost::_bi::bind_t〈R, F, boost::_bi::list1〈boost::reference_wrapper〈REFT〉〉〉 Func ) // member function(void), 不读入
void BindedCall( boost::_bi::bind_t〈R, F, boost::_bi::list2〈A1,A2〉〉 Func ) // member function(T),读入
这4种形式
知道这并不好看,将就着吧。

分离的模版具体方法参见 boost::bind 和 boost::bind_t Ref:http://blog.csdn.net/lyskyly/archive/2006/10/28/1354273.aspx

Tuesday, March 13, 2007

VS2005 编译后在其他机器中不能正常载入msvcp80.dll

FAT32清单文件的问题早就提过,就不说了。
vcredist 发布包也早装了,也不管用。
曾经的问题再度困扰着我。

在痛苦了一天之后,终于明白了,因为我曾安装了VS2005 SP1 !!!
该死的微软,在安装vs2005 sp1后,dll的版本号也从8.0.50727.42变成了8.0.50727.762,在WinSxS目录下的位置自然也变化了。而竟然,vcredist发布包只提供到.42的版本,所以sp1编译出来的东西自然就找不到dll了。
该死的微软是不是忘记更新这个vc发布包了?我们难道要傻等么?
其实可以这样:
  1. 将Windows\WinSxS下对应的目录(如x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.762_x-ww_6b128700)都copy到目标机器的WinSxS下
  2. 将Windows\WinSxS\Manifests下对应的.manifest和.cat文件copy到目标机器的WinSxS\Manifests下

无论如何,VS2005是令我最头痛的一个vs版本

Boost : VC8 : x64 编译

Boost 1_33_1 thread库要在VC8下编译为amd64版本, 搜了一下发现问题挺多,而且没什么中文资料。
废话少说
  1. 修改libs/threads/src/once.cpp, 将 return ice_wrapper(&InterlockedCompareExchange, dest, exch, cmp); ==> return InterlockedCompareExchange(dest, exch, cmp); 因为Win64下InterlockedCompareExchange成为了intrinsic function
  2. vc-8_0-x86_amd64-tools.jam中修改成: VC_SETUP = "CALL \"$(VC_TOOL_PATH)\\VCVARSx86_amd64.bat\" >nul" ;
  3. 在thread目录下run: ..\..\..\..\bjam -sTOOLS="vc-8_0-x86_amd64" -sBUILD="release debug multi/single static/dynamic"

Reference:

http://article.gmane.org/gmane.comp.lib.boost.threads.devel/13

http://en.allexperts.com/q/C-1040/Building-boost-libraries-64.htm

http://steve.chinavfx.net/?p=22

Thursday, March 01, 2007

SAGE 1 核心底层70%完工

呼,接下去最大的困难是Linux环境下的调试了。不知道那个底层够不够健壮。

顺便提一下碰到的DLL包装上的问题。
一开始生成.dll却不生成.exp和.lib导入库,最后搜破头,终于发现犯了小白错误
没有__declspec(dllexport)定义dll的调用接口。然后写上了发现出来一堆warning,最后排到后来是STL的数据也需要dllexport……这个怎么弄……。最后网上搜了半天还是disable warning的解决方案。
所以Windows下DLL包装要:

# define SAGE_DECLSPEC_IMPORT __declspec(dllimport)
# define SAGE_DECLSPEC_EXPORT __declspec(dllexport)
# define SAGE_API SAGE_DECLSPEC_EXPORT
#pragma warning (disable : 4251)

其中C4251是STL需要dllexport的警告,如果显式声明就要把STL里几乎所有的东西都声明一次了……。哎,c++还是不够美啊,只能粉饰太平眼不见为净了。
而Linux下包装DLL估计就要写DEF文件了……