用bind来解耦

#include "stdafx.h"

#define BOOST_AUTO_TEST_MAIN
#include
#include

#include
#include
#include

#include
using namespace std;

//声明一个函数指针的类型
typedef void (* ON_SEGMENT) (char * );

//用function<> 和指针回调指针来解除耦合
//注意解耦效果: CReader 和 CSaver 没有任何关系
class CReader
{

public:
CReader()
{
m_pFunc=NULL;
m_functor=NULL;

};

void UseFreeFunc(ON_SEGMENT pFunc)
{
m_pFunc=pFunc;
};

void UseFunctor(boost::function functor)
{
m_functor= functor;
};

void Read(char * pchar)
{

if(m_pFunc)
{
m_pFunc(pchar);
};

if(m_functor)
{
m_functor(pchar);
};

}
private:
ON_SEGMENT m_pFunc;//函数指针
boost::function m_functor; //函数对象
};

class CSaver
{
public:
//接受输入的字符,保存在内部变量m_str
void Input(char * pchar)
{
m_str.append(pchar);

};
string m_str;
};

BOOST_AUTO_TEST_CASE(test_bind)
{
//两个类并不知道对方的任何细节
CSaver saver;
CReader reader;

//预先 把函数 CSaver::Input 和要操作的数据 &saver 注册到 reader
//只要函数形式符合(返回值是void,传入参数是char *),都可以注册
//解除CSaver 和 CReader的耦合

//bind产生的函数对象,重载操作符()
//函数对象的本质是 函数指针加this指针,即 操作和数据
//函数对象 比 函数指针优越的地方是可以带有内部状态

reader.UseFunctor( boost::bind(&CSaver::Input, &saver, _1) );

//延时调用,解除CSaver 和 CReader的耦合
//把字符从reader 放入 saver里面
reader.Read("Hello");

reader.Read("Mafeitao");

BOOST_CHECK(saver.m_str=="HelloMafeitao");

}

//asio 里面的 async_accept 的简化版本

//可以接受 函数指针; 比如 async_accept(FreeFunc,Para)

//可以接受 函数对象; 比如
// CSaverFunctor func;
//async_accept(func,Para)

//可以接受 bind
template
void async_accept(AcceptHandler handler, Para p)
{
handler(p);
};

// 自由函数,没有内部状态
void FreeFunc(char * pChar)
{
printf("In FreeFunc %s\n", pChar);
}

BOOST_AUTO_TEST_CASE(bind_asio)
{

//类 CSaver 和 模板函数 async_accept,没有任何关系
CSaver saver;

char *pchar="Hello";

//bind生成一个临时的functor类 CSaverTemp
//类似于
/*
class CSaverTemp
{
public:
void operator ()(char * pchar)
{
m_str.append(pchar);

};
string m_str
}

CSaverTemp saver;

async_accept(saver,pchar);
}
*/

//全局函数 async_accept,接受一个bind产生的函数对象( 函数指针和this指针)
async_accept( boost::bind(&CSaver::Input, &saver,_1) , pchar);

BOOST_CHECK(saver.m_str=="Hello");

pchar="Mafeitao";

async_accept( boost::bind(&CSaver::Input, &saver,_1) , pchar);

BOOST_CHECK(saver.m_str=="HelloMafeitao");

//接受 全局函数指针,和下面的效果一样
async_accept( boost::bind(FreeFunc,_1), pchar);

//接受 全局函数指针,和上面的效果一样
async_accept( FreeFunc, pchar);

}

//带有模板函数的类
class TReader
{
public:

//模板函数
template
void Read(OnReadHandler & handler, Para p)
{
//可以接受 函数指针,参数
//可以接受 函数对象,参数
//可以接受 bind
handler(p);
};

};

BOOST_AUTO_TEST_CASE(bind_template)
{
TReader reader;
CSaver saver;

char *pchar="Hello";

reader.Read(boost::bind(&CSaver::Input, &saver,_1) , pchar);

BOOST_CHECK(saver.m_str=="Hello");

pchar="Mafeitao";

reader.Read( boost::bind(&CSaver::Input, &saver,_1) , pchar);

BOOST_CHECK(saver.m_str=="HelloMafeitao");
}

//函数对象,重载操作符()
//函数对象的本质是 函数指针加this指针,即 操作和数据
//函数对象 比 函数指针优越的地方是可以带有内部状态
class CSaverFunctor
{
public:
void operator ()(char * pchar)
{
m_str.append(pchar);

};
string m_str;
};

BOOST_AUTO_TEST_CASE(test_functor)
{
//带有模板函数的类
TReader reader;

//函数对象
CSaverFunctor saver;

//把字符从reader 放入 saver里面
char *pchar="Hello";
reader.Read( saver , pchar);

pchar="Mafeitao";
reader.Read( saver , pchar);

BOOST_CHECK(saver.m_str=="HelloMafeitao");

}

评论

完美版的 多线程 STL 全局变量 崩溃例子

 #include "stdafx.h"

#define BOOST_AUTO_TEST_MAIN
#include
#include

#include
#include
#include

#include

boost::mutex mutex;
std::set gSet;

void add_gSet(int i)
{
printf("step1 写线程 gSet.insert\n");
gSet.insert(i);

printf(" 写线程 等待30毫秒,让读线程运行起来\n\n");
Sleep(30);

printf("step3 写线程 删除set里的元素\n\n");
gSet.erase(i);

}

void show_gSet()
{

int iPos=0;
std::set::iterator pos;
while(true)
{
printf("step2 读线程 Show\n");
for(pos= gSet.begin(); pos!= gSet.end(); ++pos)
{
//printf("gSet[%d]=%d ", iPos, *pos);
iPos++;

printf(" 读线程 等待100毫秒,让写线程erase \n\n");
Sleep(100);

printf("step4 读线程 下个循环周期,将要崩溃");
}
}
}

BOOST_AUTO_TEST_CASE(test_CText2Word)
{

BOOST_CHECK( true==true);
boost::thread_group threads;

printf("完美版的 多线程 STL 全局变量 崩溃例子 \n");
printf("mafeitao www.18ie.com\n\n");
threads.create_thread( boost::bind(add_gSet,1));

//确保写线程先运行
Sleep(10);

threads.create_thread( boost::bind(show_gSet));

threads.join_all();

}

评论

diff 不同符号的含义

〈- 红色 表示 此行被移出
-〉 黄色 表示 此行是新移入的
〈! 红色 此行被删除,并且修改过
!〉 黄色 表示 此行是新增加的,并且修改过

评论

boost function 和 bind的用法的小例子

#include "stdafx.h"
#include
#include

//函数对象,重载()
struct int_div
{
float operator()(int x, int y) const { return ((float)x)/y; };
};

//自由函数
float free_div(int x, int y)
{
{ return ((float)x)/y; };
}

//成员函数
class CDiv
{
public:
float div(int x, int y)
{

return ((float)x)/y;
}

};

void test1(void)
{

//函数对象的普通用法
int_div div;
div(3,4);

//声明一个函数指针
boost::function< float(int,int )> f;

//函数对象的赋值
f=int_div();

f(1,2);
f(3,4);

//自由函数的赋值
f=free_div;
f(1,2);
f(3,4);

//f= &CDiv::div;
//编译无法通过,但如果能有此格式,最好不过

//只能用以下比较苯的方法了

//方法1 用bind
CDiv theDiv;

//类实例的地址绑定
f=boost::bind(&CDiv::div,&theDiv,_1,_2);

//类实例的赋值绑定
f=boost::bind(&CDiv::div,theDiv,_1,_2);

//方法2 重新声明一个function
//function 对成员函数的声明
boost::function< float(CDiv *,int,int )> pF;

//function 对成员函数的赋值
pF=&CDiv::div;

//function 对成员函数的调用
pF(&theDiv,1,2);

}

int _tmain(int argc, _TCHAR* argv[])
{
test1();
return 0;
}

评论

Inno Setup 对比 Nullsoft Scriptable Install System

inno 和 nullsoft 这2个安装软件,很早很早就听说过了,但一直没有使用过。 这2天对比了一下,谈一下初步印象。

inno 是用delphi写的,里面居然套了一个pascal 的脚本解释器,还可以debug ,设置断点,单步调试,奇妙的思路,令我叹为观止。安装过程中,TEdit, TMemo, TCheckBox, 大凡delphi里的控件,安装脚本都可以调用,并打包在安装文件之中。美中不足之处,是安装文件稍微大点,我测试了一下,什么文件也没有包装,就要200多K。

nullsoft 的特点是安装包非常小,符合我的口味。不太好的是需要学习它的脚本语言,对程序员来说,这也不算什么。

试过几个语法加亮的编辑器,推荐使用:HM NIS EDIT: A Free NSIS Editor/IDE

下载地址 http://hmne.sourceforge.net 感觉比较爽。但是也有美中不足,无法单步调试。

使用nullsoft install 在setup.exe 里,增加版本信息

!insertmacro MUI_LANGUAGE "SimpChinese"

  VIProductVersion "1.2.3.4"
  VIAddVersionKey /LANG=${LANG_SIMPCHINESE} "ProductName" ${PRODUCT_NAME}
  VIAddVersionKey /LANG=${LANG_SIMPCHINESE} "Comments" ""
  VIAddVersionKey /LANG=${LANG_SIMPCHINESE} "CompanyName" ${PRODUCT_PUBLISHER}
  VIAddVersionKey /LANG=${LANG_SIMPCHINESE} "LegalTrademarks" ${PRODUCT_NAME}
  VIAddVersionKey /LANG=${LANG_SIMPCHINESE} "LegalCopyright" ${PRODUCT_PUBLISHER}
  VIAddVersionKey /LANG=${LANG_SIMPCHINESE} "FileDescription" ${PRODUCT_NAME}
  VIAddVersionKey /LANG=${LANG_SIMPCHINESE} "FileVersion" ${PRODUCT_VERSION}

注意,MUI_LANGUAGE 和version只能放在脚本最后,不然会有一堆警告。
Define the LangStrings after you insert the MUI_LANGUAGE macros. Insert the MUI_LANGUAGE macros after you insert the page macros.

nullsoft 里面,增加splash画面的方法:

Function .onInit
InitPluginsDir
File /oname=$PLUGINSDIR\splash.bmp "splash.bmp"
splash::show 1000 $PLUGINSDIR\splash

用 MessageBox MB_OK $PLUGINSDIR 显示一下变量$PLUGINSDIR,发现是:
C:\Documents and Settings\z\Local Settings\Temp\nsz2A2.tmp

进入这个目录,看到splash.bmp 和 splash.dll好好地在里面躺着呢。在对比一下 C:\Program Files\NSIS\Plugins\splash.dll, 豁然开朗,原来,splash功能是nullsoft 的一个插件,如果安装软件使用了这个功能,肯定要把splash.dll打包进入setup.exe。别的插件,也应该是这样的了。53K bmp +4K DLL, 安装包只增大10多k, nullsoft 的压缩率还是很高的

在安装程序里,增加一个edit框,并把用户输入的text,写入安装目录下的配置文件里:

ReserveFile "${NSISDIR}\Plugins\InstallOptions.dll"
ReserveFile "test.ini"

;Order of pages
Page custom CreateCustom LeaveCustom ": Testing InstallOptions" ;Custom page. InstallOptions gets called in SetCustom.

Function CreateCustom

;Display the InstallOptions dialog
Push ${TEMP1}

InstallOptions::dialog "$PLUGINSDIR\test.ini"
Pop ${TEMP1}

Pop ${TEMP1}

FunctionEnd

Function LeaveCustom
ReadINIStr ${TEMP1} "$PLUGINSDIR\test.ini" "Field 3" "State"
WriteINIStr "$INSTDIR\config.ini" "ServerIp" "State" ${TEMP1}

FunctionEnd

Function .onInit

;Extract InstallOptions files
;$PLUGINSDIR will automatically be removed when the installer closes

InitPluginsDir
File /oname=$PLUGINSDIR\test.ini "test.ini"

FunctionEnd

马飞涛

评论

« Previous entries ·


Warning: MkDir failed (Disc quota exceeded) in /z1/18ie/public_html/count/wordpress/count.php on line 12

Warning: fopen("/z1/18ie/public_html/count/wordpress/2008_05/15_every.txt", "a+") - No such file or directory in /z1/18ie/public_html/count/wordpress/count.php on line 46

Warning: Supplied argument is not a valid File-Handle resource in /z1/18ie/public_html/count/wordpress/count.php on line 47

Warning: Supplied argument is not a valid File-Handle resource in /z1/18ie/public_html/count/wordpress/count.php on line 50

Warning: Supplied argument is not a valid File-Handle resource in /z1/18ie/public_html/count/wordpress/count.php on line 52

Warning: Supplied argument is not a valid File-Handle resource in /z1/18ie/public_html/count/wordpress/count.php on line 53


0.093 sec