??xml version="1.0" encoding="utf-8" standalone="yes"?>久久精品国产一区二区三区日韩,久久亚洲国产欧洲精品一,午夜精品久久影院蜜桃 http://www.shnenglu.com/shongbee2/category/10032.html杂七杂八 zh-cn Sat, 11 Dec 2010 22:32:37 GMT Sat, 11 Dec 2010 22:32:37 GMT 60 API回调成员函数 THUNK http://www.shnenglu.com/shongbee2/archive/2010/12/11/136157.htmlshongbee2 shongbee2 Sat, 11 Dec 2010 08:14:00 GMT http://www.shnenglu.com/shongbee2/archive/2010/12/11/136157.html http://www.shnenglu.com/shongbee2/comments/136157.html http://www.shnenglu.com/shongbee2/archive/2010/12/11/136157.html#Feedback 0 http://www.shnenglu.com/shongbee2/comments/commentRss/136157.html http://www.shnenglu.com/shongbee2/services/trackbacks/136157.html API只能回调全局函数Q而我们有时候希望他能回调成员函数。最常用的就?/font>Timmer 和窗口回调。要实现q个需求,׃用到 THUNK 技术?/font>THUNK 我查了一下是Q?/font>thunk 名词 n. ?/font>; ?/font>, ?。跟q个完全没有关系嘛(看来英文太烂是坏处还是挺多的Q。学习了一下之后,我理解的意思就是:狸猫换太子。替换原来意图,转调我们需要的地址?/font>
Thunk的原理其实说h很简单:巧妙的将数据D늚几个字节的数据设为特D的|然后告诉pȝQ这几个字节的数据是代码Q即一个函数指针指向这几个字节的第一个字节)Q让pȝ来执?/font> ?/span>
?font face="Times New Roman">API
回调成员函数Q?/font>
直接用成员函数的地址传给作ؓAPI 的回调函数显然会~译出错的,原因是他们的调用规则不一_ C++ ~译器不允许q样做。具体可以参考:
http://hi.baidu.com/shongbee2/blog/item/7867de9744e3c26155fb9611.html
而刚?font face="Times New Roman">THUNK技术就是让数据D当做代码断用,如果我把回调函数地址用一个数据段l他Q然后在数据D中再蟩转到成员函数的地址。这样就可以间接的调用成员函C。不错,我就是学习的q个Ҏ(gu)。嘻嘅R?/font>
大致方向知道了,q得了解一下细节,函数调用的规则:
看一?/span>http://hi.baidu.com/shongbee2/blog/item/7867de9744e3c26155fb9611.html Q也是上一文章啦。)需要注意的Q调用者怎么处理栈,被调用者怎么使用栈和处理栈。系l回调函数基本上都是_stdcall 的调用方式,成员函数?/font>__thiscall 的调用方式。他们的区别为:
关键?/span>
堆栈清除
参数传?/span>
__stdcall
被调用?/span>
参数倒序压入堆栈 ( 自右向左 )
__thiscall
被调用?/span>
压入堆栈Q?/span>this 指针保存?ECX 寄存器中
发现他们唯一不同的就?font face="Times New Roman">__thiscall?/font>this 指针保存C ECX 的寄存器中。其他都是一L。这U情冉|们就方便了,我们只需在他调用我们的时候,我们?/font>this 指针保存?/font>ECX Q然后蟩转到期望的成员函数地址可以了?/font>
//我认为思\是q样了。接下来是实玎ͼ贴源代码Q?/font>
#include "stdafx.h" #include "wtypes.h"
#include <iostream> using namespace std;
typedef void (*FUNC)(DWORD dwThis); typedef int (_stdcall *FUNC1)(int a, int b); #pragma pack(push,1) typedef struct tagTHUNK { BYTE bMovEcx; //MOVE ECX this指针Ud到ECX的指?br> DWORD dwThis; // this this指针的地址 BYTE bJmp; //jmp 跌{指o DWORD dwRealProc; //proc offset 跌{偏移
void Init(DWORD proc,void* pThis) { bMovEcx = 0xB9; //注释见下面说明^_^ dwThis = (DWORD)pThis; bJmp = 0xE9; dwRealProc = DWORD((INT_PTR)proc - ((INT_PTR)this+sizeof(THUNK))); FlushInstructionCache(GetCurrentProcess(),this,sizeof(THUNK)); } }THUNK; #pragma pack(pop) /************************************************************************************** void Init(DWORD proc,void* pThis)里面的说明: 0xB9 为MOVE ECX的指令, 0xE9 跌{的指令,q段初始化表C: 0013FF54 mov ecx, ptr [this] 0013FF59 jmp dwRealProc q个单步一下便知?br>下面那个API QFlushInstructionCacheQ查MSDNQ表C刷新缓存, 因ؓ我们修改了数据,他重新蝲入一下?/span>
我最不能理解的是jmp的偏ULZ么是那样计算Q所以这里也着重说明一下: jmp跌{的是当前指o地址的偏U,我们参数中proc是实际函数的地址Q我们需?br>把他转ؓjmp的偏U? 实际函数地址-jmp指o地址?br>实际函数地址是proc,jmp地址是((INT_PTR)this+sizeof(THUNK))Q所以就得到 dwRealProc = DWORD((INT_PTR)proc - ((INT_PTR)this+sizeof(THUNK)));q行代码 q有一点,我对汇编不了解,下面是YYQؓ什么不是: dwRealProc = DWORD((INT_PTR)proc - ((INT_PTR)this+sizeof(THUNK)) - sizeof(dwRealProc)) 直观上看jmp地址不是Qthis + sizeof(bMoveEcx) + sizeof(dwThis) + sizeof(bJmp)吗? 也就?(INT_PTR)this+sizeof(THUNK)) - sizeof(dwRealProc) 啊。可是我看了一下编译的l果Q?br>发现0013FF59 jmp dwRealProc 是一行的Q也是jmp地址实际是: ((INT_PTR)this+sizeof(THUNK)) q个地址。经q测试也没有问题Q我p为是q样了,不对的还 忘多指出。嘻嘅R?br>q有一个容易淆的Q就是我们会传入this指针Q在dwRealProc里面?FlushInstructionCache 里面都用Cthis。这里要注意啦:如果你不知道传入的参数this指针和用的q个this的话Q你p 重新复习一下C++基础了。解释一下:传入的this指针变ؓ参数pThisQ用的this是THUNK的this。^_^ *****************************************************************************************/
template<typename dst_type,typename src_type> dst_type pointer_cast(src_type src) { return *static_cast<dst_type*>( static_cast<void*>(&src) ); }
class Test { public: int m_nFirst; THUNK m_thunk; int m_nTest;
//构造函C初始化ؓ3Q仅为测试,以便查看外面的方法JmpedTest是否可以正确取得q个?br> Test() : m_nTest(3),m_nFirst(4) {}
void TestThunk() { m_thunk.Init(pointer_cast<int>(&Test::Test2),this); FUNC1 f = (FUNC1)&m_thunk; f(1,2); cout << "Test::TestThunk()" << endl; }
int Test2(int a, int b) { cout << a << " " << b << " " << m_nFirst << " " << m_nTest << endl; return 0; } };
int _tmain(int argc, _TCHAR* argv[]) { Test t; t.TestThunk(); system("pause"); return 0; }
ȝQ?/span>
q个明显是暴力的d制蟩转,直接把指令写入到数据D中Q增加了出错的风险,而且可移植性变的很差。所以尽量少用?/span>
要弄清楚函数调用规则和堆栈的q。如果你?font face="Times New Roman">_cedcl规则的函数调用的话,׃出错啦?/font>
学习代码中只是处理了单的情况Q还有几U方式,例如不是强制跌{Q而是?font face="Times New Roman">call的方式调用,也可以实现。对于其他的函数规则例如成员函数?/font>_stdcall Q他是参数压栈的Q这?/font>THUNK 的写法也不一样了。?/font>
因ؓ数据D中用到?font face="Times New Roman">this,函数回调中会用到它,所以一定要保证q个 this 有效。特别是H口回调函数Q如果释放了变量Q但是窗口没有销毁是很容易出问题的。窗口回调函C有比较喜Ƣ用一个静态的分配器,通过H口识别Q把他分配到不同的成员处理函C的方式?/font>
q个只是初学Q原因是发现ATL 的窗口回调是q样做的。觉得很奇Q所以学习了一下,有不对的地方q望多多指教。嘻嘅R。?/font>
扑ֈ的资料:
http://www.vckbase.com/document/viewdoc/?id=1821
http://www.codeproject.com/KB/cpp/GenericThunks.aspx
http://blog.csdn.net/superarhow/archive/2006/07/10/898261.aspx
http://www.cnblogs.com/homeofish/archive/2009/02/20/1395208.html
]]>诡异的强制类型{换操作符 http://www.shnenglu.com/shongbee2/archive/2009/07/28/91524.htmlshongbee2 shongbee2 Tue, 28 Jul 2009 12:03:00 GMT http://www.shnenglu.com/shongbee2/archive/2009/07/28/91524.html http://www.shnenglu.com/shongbee2/comments/91524.html http://www.shnenglu.com/shongbee2/archive/2009/07/28/91524.html#Feedback 2 http://www.shnenglu.com/shongbee2/comments/commentRss/91524.html http://www.shnenglu.com/shongbee2/services/trackbacks/91524.html 最q在学习中,看到了一D很诡异的代码?br>
CComptr < IDispatch > ptrDisp; IDispatch * pDisp = ptrDisp;
Ҏ(gu)很是疑惑Qؓ什么两个完全不同的cd可以无差别的转换?br>猜测1Q?br>认ؓIDispatch重蝲了赋值操作符?.1U的旉否定。他只是一个接口,定义很明的4的方法。不可能。由于不怿Q还Ҏ(gu)ȝ了一下他的接口定义。彻底死心?br>猜测2. CComptr<IDispatch>重蝲了赋值操作符。但是想来想d该和他的重蝲没有关系Q因个操作在他的左边Q和他的赋值操作符全然没有关系。不信之Q进ȝ了一下,q且把重载给注释掉,l果q是能编译成功,d信不是赋值的作用?br> 真相Q?br>l于拿出杀手锏QF11Q单步,哈哈Q进d现原来有Q?br>
operator T * () const throw () { return p; }
q段代码。哈哈。。问了大牛知道是重蝲强制转换。哈哈。纵Ʋ知道原因了。。?br>自己也模仿写了一下:
class A1 { public : int operator * () { return 6 ; } operator int () // const { return 6 ; } }; int main() { int a( 5 ); int a1 = int ( 6 ); A1 aa1; int a2 = aa1; return 0 ; }
~译成功Q爽。。。?br>
]]> 万恶的listView控g http://www.shnenglu.com/shongbee2/archive/2009/07/28/91513.htmlshongbee2 shongbee2 Tue, 28 Jul 2009 09:28:00 GMT http://www.shnenglu.com/shongbee2/archive/2009/07/28/91513.html http://www.shnenglu.com/shongbee2/comments/91513.html http://www.shnenglu.com/shongbee2/archive/2009/07/28/91513.html#Feedback 0 http://www.shnenglu.com/shongbee2/comments/commentRss/91513.html http://www.shnenglu.com/shongbee2/services/trackbacks/91513.html 用v来很不错。可惜响应消息就ȝ很多。一个右键弹单,居然弄的要用钩子。之后才发现是消息响应错了。是应该响应 OnRClickcM的消息吧(忘了)QLButtonDown什么的p惌得了。。还有什么OwnerData什么的又是一大堆的消息,响应的都郁闷。然后我的策略就是直接用他自q。哈哈。一个消息不响应。。。?br>{有旉了,一定要学一个listView控g的专题?C++?。。一定要努力学习。。加沏V。?img src ="http://www.shnenglu.com/shongbee2/aggbug/91513.html" width = "1" height = "1" /> ]]> 【{】基于Thunk实现的类成员消息处理函数 http://www.shnenglu.com/shongbee2/archive/2009/07/23/90908.htmlshongbee2 shongbee2 Thu, 23 Jul 2009 03:35:00 GMT http://www.shnenglu.com/shongbee2/archive/2009/07/23/90908.html http://www.shnenglu.com/shongbee2/comments/90908.html http://www.shnenglu.com/shongbee2/archive/2009/07/23/90908.html#Feedback 0 http://www.shnenglu.com/shongbee2/comments/commentRss/90908.html http://www.shnenglu.com/shongbee2/services/trackbacks/90908.html http://blog.csdn.net/JerKii/archive/2006/04/07/654188.aspx ׃比较多,直接贴链接了?br>郁闷的是我死zL有弄成功。。唉Q只有l加油咯。。?img src ="http://www.shnenglu.com/shongbee2/aggbug/90908.html" width = "1" height = "1" /> ]]> 字符~码转换Qؓ什么我的ICONV不能用啊Q?/title> http://www.shnenglu.com/shongbee2/archive/2009/07/10/89730.htmlshongbee2 shongbee2 Fri, 10 Jul 2009 07:23:00 GMT http://www.shnenglu.com/shongbee2/archive/2009/07/10/89730.html http://www.shnenglu.com/shongbee2/comments/89730.html http://www.shnenglu.com/shongbee2/archive/2009/07/10/89730.html#Feedback 0 http://www.shnenglu.com/shongbee2/comments/commentRss/89730.html http://www.shnenglu.com/shongbee2/services/trackbacks/89730.html 哎,找了半天转换Q找CICONVQ据说是跨^台的Q很牛。下载的libxml也需要到他,也下载了他的库,׃libxml转换~码格式?/p>
可是用来用去都不正确。网上去扄资料都是一个版本的Q我最后的代码为:
bool charToUtf_8(IN const char * strSrc, IN OUT char ** pstrDst) { // u2g(in_utf8,strlen(in_utf8),out,OUTLEN); iconv_t cd = iconv_open( " utf-8 " , " ANSI_X3.4-1986 " ); // iconv_t cd = iconv_open("utf-8", "CP_ACP"); if (cd == (iconv_t)( - 1 )) { return false ; } size_t ilen = ::strlen(strSrc) + 1 ; size_t olen = ilen * 4 ; char * inbuf = new char [ilen]; char * outbuf = new char [olen]; memset(inbuf, 0 , ilen); memset(outbuf, 0 , olen); const char * in = inbuf; char * out = outbuf; // memcpy(inbuf, strSrc, ilen); size_t ret = iconv(cd, & in , & ilen, & out , & olen); // 下面q种方式会出错,Z? // size_t ret = iconv(cd, &inbuf, &ilen, &outbuf, &olen); // if (ret == (size_t)(-1)) // { // cerr << "iconv error" << endl; // } // else // { // cout << outbuf << endl; // } delete[] inbuf; delete outbuf; iconv_close(cd); return true ; }
当然q些代码是从|上拯下来再改的。编译通过Q运行就不行了?/p>
后来我放弃了。直接用windows的方法。(q好我是在windows上开发)
bool CharToUtf_8(IN const char * strSrc, IN OUT char ** pstrDst) { assert(pstrDst); int nSize = MultiByteToWideChar(CP_ACP,NULL, strSrc, - 1 , NULL, 0 ); WCHAR * pwchTemp = new WCHAR[nSize]; nSize = MultiByteToWideChar(CP_ACP,NULL, strSrc, - 1 , pwchTemp, nSize); nSize = WideCharToMultiByte(CP_UTF8, NULL, pwchTemp, - 1 , NULL, 0 , 0 , 0 ); * pstrDst = new char [nSize]; nSize = WideCharToMultiByte(CP_UTF8, NULL, pwchTemp, - 1 , * pstrDst, nSize, 0 , 0 ); return true ; }
q样可以饿了。呵c。哎。。。?br>不过挺郁LQؓ什么ICONV不能用啊Q有高手指点一下吗Q?/p>
]]> VS2008讄内存断点 http://www.shnenglu.com/shongbee2/archive/2009/07/08/89571.htmlshongbee2 shongbee2 Wed, 08 Jul 2009 13:55:00 GMT http://www.shnenglu.com/shongbee2/archive/2009/07/08/89571.html http://www.shnenglu.com/shongbee2/comments/89571.html http://www.shnenglu.com/shongbee2/archive/2009/07/08/89571.html#Feedback 0 http://www.shnenglu.com/shongbee2/comments/commentRss/89571.html http://www.shnenglu.com/shongbee2/services/trackbacks/89571.html 菜鸟的我居然不知道什么是内存断点?br>自己理解一下:内存断点是当某个内存改变的时候会断下来的。就跟程序断点一Pq行到那里就断下来一栗?br>VS2008怎么讄内存断点呢。我打开内存监视器。按F9是没有效果的Q给出错误提C。后来通过|上搜了才知道原来是q样讄的哦Q哈哈?br>截图什么的q了,因ؓ我觉得我对VS2008的界面应该还是比较了解的吧。哈?br> 1.内存断点只能是在E序调试q行的时候才能设|的。这跟普通的代码断点不一栗?br>2.q入调试状态,Q按F5啦)Q设|一个要监控的内存的变量哪里讄断点先断下来。(我是q样做的Q?br>3.断下来之后,哈哈Q关键:点击菜单栏的Debug->new Breakpoint-> new DataBreakPoint。这是讄内存的断点啦?br>4 。点M后会出来一个设|内存断点的对话框,填好好断的内存就可以了。上面的地址是可以直接用变量名加取地址W的。例?amp;aQ其他的应该好理解Q监控的长度和语a。设|就O(jin)K了,哈哈?br>今天有学了一招,以后如果想知道内存什么时候被改变Q俺׃怕啦。。?/p> ]]> gtest学习文章 http://www.shnenglu.com/shongbee2/archive/2009/07/08/89531.htmlshongbee2 shongbee2 Wed, 08 Jul 2009 02:28:00 GMT http://www.shnenglu.com/shongbee2/archive/2009/07/08/89531.html http://www.shnenglu.com/shongbee2/comments/89531.html http://www.shnenglu.com/shongbee2/archive/2009/07/08/89531.html#Feedback 0 http://www.shnenglu.com/shongbee2/comments/commentRss/89531.html http://www.shnenglu.com/shongbee2/services/trackbacks/89531.html 现在要用gtest框架写单元测试。所以网上找了一个学习资料(或是教程Q呵呵,因ؓ我的基础很烂Q直接看官方的文档可能不是很会。谢谢提供者?br>文章地址Q?a >http://www.cnblogs.com/coderzh/archive/2009/04/06/1426758.html q是一个系列的Q希望早日看完。哈哈,加a。。?/p> ]]> STL_Map的简单实?/title> http://www.shnenglu.com/shongbee2/archive/2009/04/05/79029.htmlshongbee2 shongbee2 Sun, 05 Apr 2009 10:11:00 GMT http://www.shnenglu.com/shongbee2/archive/2009/04/05/79029.html http://www.shnenglu.com/shongbee2/comments/79029.html http://www.shnenglu.com/shongbee2/archive/2009/04/05/79029.html#Feedback 0 http://www.shnenglu.com/shongbee2/comments/commentRss/79029.html http://www.shnenglu.com/shongbee2/services/trackbacks/79029.html
#include < iostream > #include< map > using namespace std; int main() { typedef map < int , int > Map_DInt; typedef pair < int , int > Map_Pair; Map_DInt map1; // empty是检map是否为空 if (map1.empty()) // 是否ؓI如果ؓI,输出 { cout << " empty\n " ; } map1[3 ] = 30 ; // 因ؓmap重蝲了[]可以通过[]直接d数据和查找数?/span> map1.insert(Map_DInt::value_type( 4 , 40 )); // d数据4(key), 40(value) map1.insert(Map_Pair( 1 , 10 )); // d数据1,10 // 遍历节点Qƈ输出对应的key和value for (Map_DInt::iterator it1 = map1.begin(); it1 != map1.end(); ++ it1) { cout << " Key: " << it1 -> first << " Value: " << it1 -> second << endl; } // []也可以直接用于查找,但是如果没有扑ֈQ他会默认加一个Dȝ Map_DInt::iterator it1; it1 = map1.find( 5 ); // 查找key ?的数?/span> if (it1 != map1.end()) // 如果扑ֈQ则输出他的数据 { cout << it1 -> second << endl; } else // 否则输出找不?/span> { cout << " Not Found\n " ; } if (map1[ 5 ] != 0 ) { cout << map1[ 5 ] << endl; } else { cout << " Not Found\n " ; } it1 = map1.find( 5 ); // 查找key ?的数?/span> if (it1 != map1.end()) // 如果扑ֈQ则输出他的数据 { cout << it1 -> second << endl; } else // 否则输出找不?/span> { cout << " Not Found\n " ; } map1[5 ] = 50 ; // 更改相应的?/span> it1 = map1.find( 5 ); // 查找key ?的数?/span> if (it1 != map1.end()) // 如果扑ֈQ则输出他的数据 { cout << it1 -> second << endl; } else // 否则输出找不?/span> { cout << " Not Found\n " ; } size_t nNum = map1.erase( 5 ); // 删除数据 map1.clear(); // 清楚所有数?/span> system(" pause " ); return 0 ; }
]]> 【{】STL map常用操作?/title> http://www.shnenglu.com/shongbee2/archive/2009/04/05/79026.htmlshongbee2 shongbee2 Sun, 05 Apr 2009 09:48:00 GMT http://www.shnenglu.com/shongbee2/archive/2009/04/05/79026.html http://www.shnenglu.com/shongbee2/comments/79026.html http://www.shnenglu.com/shongbee2/archive/2009/04/05/79026.html#Feedback 0 http://www.shnenglu.com/shongbee2/comments/commentRss/79026.html http://www.shnenglu.com/shongbee2/services/trackbacks/79026.html 转自Q?a >http://www.cnblogs.com/TianFang/archive/2006/12/30/607859.html 1。目?
map?
map的功?
使用map
在map中插入元?
查找q获取map中的元素
从map中删除元?
2。map?
map是一c?span style="COLOR: red">兌式容?/span>。它的特Ҏ(gu)增加和删除节点对q代器的影响很小 Q除了那个操作节点,对其他的节点都没有什么媄响。对于P代器来说Q可以修改实|而不能修改key?
3。map的功?
自动建立Key Q?value的对应。key ?value可以是Q意你需要的cd?
Ҏ(gu)key值快速查找记录,查找的复杂度基本是Log(N)Q如果有1000个记录,最多查?0ơ,1,000,000个记录,最多查?0ơ?
快速插入Key - Value 记录?
快速删除记?
Ҏ(gu)Key 修改value记录?
遍历所有记录?
4。用map
使用map得包含mapcL在的头文?br>#include <map> //注意QSTL头文件没有扩展名.h
map对象是模板类Q需要关键字和存储对象两个模板参敎ͼ std:map<int, string> personnel; q样定义了一个用int作ؓ索引,q拥有相兌的指向string的指?
Z使用方便Q可以对模板c进行一下类型定义,
typedef map<int, CString> UDT_MAP_INT_CSTRING; UDT_MAP_INT_CSTRING enumMap;
5。在map中插入元?
改变map中的条目非常单,因ؓmapcdl对[]操作W进行了重蝲
enumMap[1] = "One"; enumMap[2] = "Two"; .....
q样非常直观Q但存在一个性能的问题?span style="COLOR: #9bbb59">插入2?先在enumMap中查找主键ؓ2的项Q没发现Q然后将一个新的对象插入enumMapQ键?Q值是一个空字符Ԍ插入完成后,字W串赋ؓ"Two"; 该方法会每个值都赋ؓ~省|然后再赋为显C的|如果元素是类对象Q则开销比较大。我们可以用以下Ҏ(gu)来避免开销Q?
enumMap.insert (map<int, CString> :: value_type(2, "Two"))
6。查扑ƈ获取map中的元素
下标操作W给Z获得一个值的最单方法:
CString tmp = enumMap[2];
但是,只有当map中有q个键的实例时才?/span>Q否则会自动?span style="COLOR: #548dd4">入一个实例,gؓ初始化?/span>?
我们可以使用Find()和Count()Ҏ(gu)来发C个键是否存在?
查找map中是否包含某个关键字条目?span style="COLOR: #f79646">find()Ҏ(gu)Q传入的参数是要查找的keyQ在q里需要提到的是begin()和end()两个成员Q分别代表map对象中第一个条目和最后一个条目,q两个数据的cd是iterator.
int nFindKey = 2; //要查扄Key //定义一个条目变?实际是指? UDT_MAP_INT_CSTRING::iterator it= enumMap.find(nFindKey); if(it == enumMap.end()) { //没找?br>} else { //扑ֈ }
通过map对象的方法获取的iterator数据cd是一个std::pair对象Q包括两个数?iterator->first ?iterator->second 分别代表关键字和存储的数?
7。从map中删除元?
U除某个map中某个条目用erase()
该成员方法的定义如下
iterator erase(iterator it); //通过一个条目对象删?
iterator erase(iterator first, iterator last); //删除一个范?
size_type erase(const Key& key); //通过关键字删?
clear() q当于 enumMap.erase(enumMap.begin(), enumMap.end());
]]> STL中set的简单学?/title> http://www.shnenglu.com/shongbee2/archive/2009/04/05/79011.htmlshongbee2 shongbee2 Sun, 05 Apr 2009 06:58:00 GMT http://www.shnenglu.com/shongbee2/archive/2009/04/05/79011.html http://www.shnenglu.com/shongbee2/comments/79011.html http://www.shnenglu.com/shongbee2/archive/2009/04/05/79011.html#Feedback 2 http://www.shnenglu.com/shongbee2/comments/commentRss/79011.html http://www.shnenglu.com/shongbee2/services/trackbacks/79011.html
#include < iostream > #include< set > using namespace std; int main() { set < int > st1; // 创徏一个intcd的set set < int > ::iterator it1; // 创徏一个他对应的P代器 // empty是判断他是否为空Q而且如果要判断空Q最好用q个来判?br> // 如果为空q回true if (st1.empty()) // 判断I?如果是空Q则输出empty { cout << " empty\n " ; } // 查找数据Qfind。返回值是扑ֈ的情늚q代器,如果没有扑ֈQ?br> // q代器只想endQ如果找刎ͼ为找到的数据Q所以这里一定要?br> // 判断一下是否找到数据了?/span> it1 = st1.find( 40 ); // 查找数据 if (it1 != st1.end()) // 如果扑ֈp出数?/span> { cout << * it1 << endl; } // 插入数据?/span> st1.insert( 10 ); // 插入数据 st1.insert( 30 ); st1.insert( 20 ); st1.insert( 40 ); // 遍历数据Q用q代器遍历数?/span> for (it1 = st1.begin(); it1 != st1.end(); ++ it1) { cout << * it1 << endl; } // 因ؓ开始没?0q个元素Q所以找不到Q现在插入了Q再 // L一下。呵呵,扑ֈ了?/span> it1 = st1.find( 40 ); // 查找数据 if (it1 != st1.end()) // 如果扑ֈp出数?/span> { cout << * it1 << endl; } // 删除数据q里q回的是删除的个数。在q里当然??/span> size_t kk = st1.erase( 40 ); cout << kk << endl; // 清除全部数据?/span> st1.clear(); system( " pause " ); return 0 ; }
]]> 【{】函数调用的一些约定__cdecl __fastcall?__stdcall http://www.shnenglu.com/shongbee2/archive/2009/04/02/78672.htmlshongbee2 shongbee2 Thu, 02 Apr 2009 04:52:00 GMT http://www.shnenglu.com/shongbee2/archive/2009/04/02/78672.html http://www.shnenglu.com/shongbee2/comments/78672.html http://www.shnenglu.com/shongbee2/archive/2009/04/02/78672.html#Feedback 0 http://www.shnenglu.com/shongbee2/comments/commentRss/78672.html http://www.shnenglu.com/shongbee2/services/trackbacks/78672.html __cdecl __fastcall?__stdcall 调用U定Q? __cdecl __fastcall?__stdcallQ三者都是调用约?Calling convention)Q它军_以下内容Q?)函数参数的压栈顺序,2)p用者还是被调用者把参数弹出栈,3)以及产生函数修饰名的Ҏ(gu)? 1、__stdcall调用U定Q函数的参数自右向左通过栈传递,被调用的函数在返回前清理传送参数的内存栈, 2、_cdecl是C和CQ+E序的缺省调用方式。每一个调用它的函数都包含清空堆栈的代码,所以生的可执行文件大会比调用_stdcall函数的大。函数采用从叛_左的压栈方式。注意:对于可变参数的成员函敎ͼ始终使用__cdecl的{换方式? 3、__fastcall调用U定Q它是通过寄存器来传送参数的Q实际上Q它用ECX和EDX传送前两个双字QDWORDQ或更小的参敎ͼ剩下的参C旧自叛_左压栈传送,被调用的函数在返回前清理传送参数的内存栈)? 4、thiscall仅仅应用?C++"成员函数。this指针存放于CX寄存器,参数从右到左压。thiscall不是关键词,因此不能被程序员指定? 5?
naked
call采用1-4的调用约定时Q如果必要的话,q入函数时编译器会生代码来保存ESIQEDIQEBXQEBP寄存器,退出函数时则生代码恢复这?
寄存器的内容。naked call不生这L代码。naked call不是cd修饰W,故必d_declspec共同使用? 调用U定可以通过工程讄QSetting...\C/C++ \Code Generation进行选择Q缺省状态ؓ__cdecl? 名字修饰U定Q? 1、修饰名(Decoration name)Q?C"或?C++"函数在内部(~译和链接)通过修饰名识? 2、C~译时函数名修饰U定规则Q? __stdcall调用U定在输出函数名前加上一个下划线前缀Q后面加上一?@"W号和其参数的字节数Q格式ؓ_functionname@number,例如 Qfunction(int a, int b)Q其修饰名ؓQ_function@8 __cdecl调用U定仅在输出函数名前加上一个下划线前缀Q格式ؓ_functionname? __fastcall调用U定在输出函数名前加上一?@"W号Q后面也是一?@"W号和其参数的字节数Q格式ؓ@functionname@number? 3、C++~译时函数名修饰U定规则Q? __stdcall调用U定Q? 1)、以"?"标识函数名的开始,后跟函数名; 2)、函数名后面?@@YG"标识参数表的开始,后跟参数表; 3)、参数表以代可C: X--void Q? D--charQ? E--unsigned charQ? F--shortQ? H--intQ? I--unsigned intQ? J--longQ? K--unsigned longQ? M--floatQ? N--doubleQ? _N--boolQ? PA--表示指针Q后面的代号表明指针cdQ如果相同类型的指针q箋出现Q以"0"代替Q一?0"代表一ơ重复; 4)、参数表的第一ؓ该函数的q回值类型,其后依次为参数的数据cd,指针标识在其所指数据类型前Q? 5)、参数表后以"@Z"标识整个名字的结束,如果该函数无参数Q则?Z"标识l束? 其格式ؓ"?functionname@@YG*****@Z"??functionname@@YG*XZ"Q例? int Test1(char *var1,unsigned long)-----“?Test1@@YGHPADK@Z” void Test2() -----“?Test2@@YGXXZ” __cdecl调用U定Q? 规则同上面的_stdcall调用U定Q只是参数表的开始标识由上面?@@YG"变ؓ"@@YA"? __fastcall调用U定Q? 规则同上面的_stdcall调用U定Q只是参数表的开始标识由上面?@@YG"变ؓ"@@YI"? VC++对函数的省缺声明?__cedcl",只能被C/C++调用. 注意Q? 1、_beginthread需要__cdecl的线E函数地址Q_beginthreadex和CreateThread需要__stdcall的线E函数地址? 2、一般WIN32的函数都是__stdcall。而且在Windef.h中有如下的定义: #define CALLBACK __stdcall #define WINAPI __stdcall 3、extern "C" _declspec(dllexport) int __cdecl Add(int a, int b); typedef int (__cdecl*FunPointer)(int a, int b); 修饰W的书写序如上? 4?
extern "C"的作用:如果Add(int a, int
b)是在c语言~译器编译,而在c++文g使用Q则需要在c++文g中声明:extern "C" Add(int a, int
b)Q因为c~译器和c++~译器对函数名的解释不一Pc++~译器解释函数名的时候要考虑函数参数Q这h了方便函数重载,而在c语言中不存在函数?
载的问题Q,使用extern "C"Q实质就是告诉c++~译器,该函数是c库里面的函数。如果不使用extern "C"则会出现链接错误? 一般象如下使用Q? #ifdef _cplusplus #define EXTERN_C extern "C" #else #define EXTERN_C extern #endif #ifdef _cplusplus extern "C"{ #endif EXTERN_C int func(int a, int b); #ifdef _cplusplus } #endif 5、MFC提供了一些宏Q可以用AFX_EXT_CLASS来代替__declspec(DLLexport)Qƈ修饰cdQ从而导出类QAFX_API_EXPORT来修饰函敎ͼAFX_DATA_EXPORT来修饰变? AFX_CLASS_IMPORTQ__declspec(DLLexport) AFX_API_IMPORTQ__declspec(DLLexport) AFX_DATA_IMPORTQ__declspec(DLLexport) AFX_CLASS_EXPORTQ__declspec(DLLexport) AFX_API_EXPORTQ__declspec(DLLexport) AFX_DATA_EXPORTQ__declspec(DLLexport) AFX_EXT_CLASSQ?ifdef _AFXEXT AFX_CLASS_EXPORT #else AFX_CLASS_IMPORT 6?
DLLMain负责初始?Initialization)和结?Termination)工作Q每当一个新的进E或者该q程的新的线E访问DLLӞ
或者访问DLL的每一个进E或者线E不再用DLL或者结束时Q都会调用DLLMain。但是,使用TerminateProcess?
TerminateThreadl束q程或者线E,不会调用DLLMain? 7、一个DLL在内存中只有一个实? DLLE序和调用其输出函数的程序的关系Q? 1)、DLL与进E、线E之间的关系 DLL模块被映到调用它的q程的虚拟地址I间? DLL使用的内存从调用q程的虚拟地址I间分配Q只能被该进E的U程所讉K? DLL的句柄可以被调用q程使用Q调用进E的句柄可以被DLL使用? DLLDLL可以有自q数据D,但没有自q堆栈Q用调用进E的栈,与调用它的应用程序相同的堆栈模式? 2)、关于共享数据段 DLL
定义的全局变量可以被调用进E访问;DLL可以讉K调用q程的全局数据。用同一DLL的每一个进E都有自qDLL全局变量实例。如果多个线Eƈ发访?
同一变量Q则需要用同步机Ӟ对一个DLL的变量,如果希望每个使用DLL的线E都有自q|则应该用线E局部存?TLSQThread
Local Strorage)?br>
]]> [转]C++操作W号的优先 http://www.shnenglu.com/shongbee2/archive/2009/04/01/78561.htmlshongbee2 shongbee2 Wed, 01 Apr 2009 05:44:00 GMT http://www.shnenglu.com/shongbee2/archive/2009/04/01/78561.html http://www.shnenglu.com/shongbee2/comments/78561.html http://www.shnenglu.com/shongbee2/archive/2009/04/01/78561.html#Feedback 0 http://www.shnenglu.com/shongbee2/comments/commentRss/78561.html http://www.shnenglu.com/shongbee2/services/trackbacks/78561.html 原文地址Qhttp://www.cppreference.com/wiki/operator_precedence
哈哈。以后不用到处去看书啦。谢谢那个哥们?br>
Operator
Description
Example
Overloadable
Group 1 (no associativity)
::
Scope resolution operator
Class::age = 2;
NO
Group 2
()
Function call
isdigit('1')
YES
()
Member initalization
c_tor(int x, int y) : _x(x), _y(y*10){};
YES
[]
Array access
array[4] = 2;
YES
->
Member access from a pointer
ptr->age = 34;
YES
.
Member access from an object
obj.age = 34;
NO
++
Post-increment
for( int i = 0; i < 10; i++ ) cout << i;
YES
--
Post-decrement
for( int i = 10; i > 0; i-- ) cout << i;
YES
const_cast
Special cast
const_cast<type_to>(type_from);
NO
dynamic_cast
Special cast
dynamic_cast<type_to>(type_from);
NO
static_cast
Special cast
static_cast<type_to>(type_from);
NO
reinterpret_cast
Special cast
reinterpret_cast<type_to>(type_from);
NO
typeid
Runtime type information
cout « typeid(var).name();
cout « typeid(type).name();
NO
Group 3 (right-to-left associativity)
!
Logical negation
if( !done ) …
YES
not
Alternate spelling for !
~
Bitwise complement
flags = ~flags;
YES
compl
Alternate spelling for ~
++
Pre-increment
for( i = 0; i < 10; ++i ) cout << i;
YES
--
Pre-decrement
for( i = 10; i > 0; --i ) cout << i;
YES
-
Unary minus
int i = -1;
YES
+
Unary plus
int i = +1;
YES
*
Dereference
int data = *intPtr;
YES
&
Address of
int *intPtr = &data;
YES
new
Dynamic memory allocation
long *pVar = new long;
MyClass *ptr = new MyClass(args);
YES
new []
Dynamic memory allocation of array
long *array = new long[n];
YES
delete
Deallocating the memory
delete pVar;
YES
delete []
Deallocating the memory of array
delete [] array;
YES
(type)
Cast to a given type
int i = (int) floatNum;
YES
sizeof
Return size of an object or type
int size = sizeof floatNum;
int size = sizeof(float);
NO
Group 4
->*
Member pointer selector
ptr->*var = 24;
YES
.*
Member object selector
obj.*var = 24;
NO
Group 5
*
Multiplication
int i = 2 * 4;
YES
/
Division
float f = 10.0 / 3.0;
YES
%
Modulus
int rem = 4 % 3;
YES
Group 6
+
Addition
int i = 2 + 3;
YES
-
Subtraction
int i = 5 - 1;
YES
Group 7
<<
Bitwise shift left
int flags = 33 << 1;
YES
>>
Bitwise shift right
int flags = 33 >> 1;
YES
Group 8
<
Comparison less-than
if( i < 42 ) …
YES
<=
Comparison less-than-or-equal-to
if( i <= 42 ) ...
YES
>
Comparison greater-than
if( i > 42 ) …
YES
>=
Comparison greater-than-or-equal-to
if( i >= 42 ) ...
YES
Group 9
==
Comparison equal-to
if( i == 42 ) ...
YES
eq
Alternate spelling for ==
!=
Comparison not-equal-to
if( i != 42 ) …
YES
not_eq
Alternate spelling for !=
Group 10
&
Bitwise AND
flags = flags & 42;
YES
bitand
Alternate spelling for &
Group 11
^
Bitwise exclusive OR (XOR)
flags = flags ^ 42;
YES
xor
Alternate spelling for ^
Group 12
|
Bitwise inclusive (normal) OR
flags = flags | 42;
YES
bitor
Alternate spelling for |
Group 13
&&
Logical AND
if( conditionA && conditionB ) …
YES
and
Alternate spelling for &&
Group 14
||
Logical OR
if( conditionA || conditionB ) ...
YES
or
Alternate spelling for ||
Group 15 (right-to-left associativity)
? :
Ternary conditional (if-then-else)
int i = (a > b) ? a : b;
NO
Group 16 (right-to-left associativity)
=
Assignment operator
int a = b;
YES
+=
Increment and assign
a += 3;
YES
-=
Decrement and assign
b -= 4;
YES
*=
Multiply and assign
a *= 5;
YES
/=
Divide and assign
a /= 2;
YES
%=
Modulo and assign
a %= 3;
YES
&=
Bitwise AND and assign
flags &= new_flags;
YES
and_eq
Alternate spelling for &=
^=
Bitwise exclusive or (XOR) and assign
flags ^= new_flags;
YES
xor_eq
Alternate spelling for ^=
|=
Bitwise normal OR and assign
flags |= new_flags;
YES
or_eq
Alternate spelling for |=
<<=
Bitwise shift left and assign
flags <<= 2;
YES
>>=
Bitwise shift right and assign
flags >>= 2;
YES
Group 17
throw
throw exception
throw EClass(“Message”);
NO
Group 18
,
Sequential evaluation operator
for( i = 0, j = 0; i < 10; i++, j++ ) …
YES
哎,效果没有那里好。看来操作还需要练习。呵?br> ]]> c++操作W重?/title> http://www.shnenglu.com/shongbee2/archive/2009/04/01/78554.htmlshongbee2 shongbee2 Wed, 01 Apr 2009 05:10:00 GMT http://www.shnenglu.com/shongbee2/archive/2009/04/01/78554.html http://www.shnenglu.com/shongbee2/comments/78554.html http://www.shnenglu.com/shongbee2/archive/2009/04/01/78554.html#Feedback 6 http://www.shnenglu.com/shongbee2/comments/commentRss/78554.html http://www.shnenglu.com/shongbee2/services/trackbacks/78554.html 阅读全文 ]]>
þҹɫƷAV
|
ձǿƬþþþþAAA |
þþþƷҰ |
vaþþþ |
þþƷ99þ㽶 |
þþþþþþþ |
˾ƷۺϾþþ |
99þþƷһ |
Ʒþˬۺ |
þˬˬƬAV鶹 |
ó˾þAvѸ |
þAAAAƬһ |
þþù |
Ӱһþþþó˾Ʒۺ
|
Ļþ |
þ99Ʒ99þ |
һaɫƬþٸһHƬѷ
|
㽶þҹɫƷ2020 |
þҹ³˿Ƭ |
ճˮþƷtv |
þƵۿ |
ƷþavĻ |
þҹ³˿Ƭϼ
|
ľþþƷww16 |
Ʒþþþ |
þþŮ붯ȺëƬ |
þƷVA |
˾þþƷ |
þþþþþž99Ʒ |
þӰ |
AVһþ |
99þֻоƷ |
AVݺɫۺϾþ |
ĻӰӾþþѹۿ |
ۺþþ |
Ʒþþþ
|
99þùۺϾƷŮͬͼƬ |
һþ㽶 |
˾þþƷ |
Ʒ99þ |
þ߿߿ |