tinyxml使用技巧
实在是好用呀,优点比如:
1,一次装载到内存,其它地方全用引用即可,一个小指针可以是一个元素,也可是一个节(内部很多子元素)。
2,不用管理元素的内存回收,我是没看源码,号称管理的很好。一个父元素删除,它包含的所有子都释放了。
3,api较少并且,一目了然。
遍历时基本就用三个算法:
1)同级的循环(没用遍历以防会误解包括子节点处理)
//pParent当然是父了
for (TiXmlNode *pSTATE = pParent->FirstChild( “STATE” ); pSTATE; pSTATE = pSTATE->NextSibling(“STATE” ))
{}
注意:要用TiXmlNode *结构,不要用TiXmlElement*
2)当同级的到了最后一个,NextSibling()会返回个空。这时你可以用跳了。
pParent->IterateChildren( pSTATE )
3)以上两个掌握了,就可以玩遍历了。不过,要注意,走到叶子节点时,要跳级。但如果你手工跳了,可能遍历会有重复情况。这时可以使用函数的静态变量喽。可以用静态变量记住父结点。可以用静态list来存放处理过的节点,跳过重复情况。示例代码如下:
void handleExportMap(TiXmlNode * pSrc)
{
if (!pSrc ) return;
static TiXmlNode *bodyItem;
if (“FRAME_BODY” == pSrc->ValueTStr())
{
bodyItem = pSrc ;
}
static TiXmlNode *curpItem;
int t = pSrc ->Type();
printf( “type %d \n” , t);
switch (t)
{
case TiXmlNode :: TINYXML_DOCUMENT:
printf( “Document” );
break ;
case TiXmlNode :: TINYXML_ELEMENT:
printf( “Element [%s]” , pSrc ->Value());
//
if (“CONTENT” == pSrc->ValueTStr())
{
curpItem = pSrc ;
}
if (“MAP” == pSrc->ValueTStr())
{
//跳过MAP的处理
pSrc = curpItem->IterateChildren(pSrc ->Parent());
if (!pSrc )
return ;
else
printf( “Element [%s]” , pSrc ->Value());
}
if (“STATE” == pSrc->ValueTStr() && pSrc == pSrc ->Parent()->LastChild())
{
//跳过STATE的处理
//map中的state
pSrc = curpItem->IterateChildren(pSrc ->Parent()->Parent());
if (!pSrc )
return ;
else
printf( “Element [%s]” , pSrc ->Value());
}
if (“ITEM” == pSrc->ValueTStr())
{
printf( “Element [%s]” , pSrc ->Value());
if (!pSrc ->NoChildren())
{
if (!bMoveItems(pSrc ))
return ;
}
} //end if (!pSrc->NoChildren())
if (“MESSAGE” == pSrc->ValueTStr())
{
curpItem = pSrc ;
if (!bMoveItems(pSrc ))
return ;
}
break ;
case TiXmlNode :: TINYXML_COMMENT:
printf( “Comment: [%s]” , pSrc ->Value());
break ;
case TiXmlNode :: TINYXML_UNKNOWN:
printf( “Unknown” );
break ;
case TiXmlNode :: TINYXML_TEXT:
printf( “Text: [%s]\n” , pSrc ->ToText()->Value());
break ;
case TiXmlNode :: TINYXML_DECLARATION:
printf( “Declaration” );
break ;
default :
break ;
}
if (pSrc ->NoChildren())
{
pSrc = pSrc ->NextSibling();
handleExportMap( pSrc );
}
else
{
//过滤,直到合法
while (pSrc = pSrc->FirstChild())
{
handleExportMap( pSrc );
}
}
}
在这个遍历的框架基础上,可以变化和设计出你的需求了,注意,要分化任务,只做遍历,和只做节点的处理,不要混在一起,不然,一个bug两三天呀。上面的bMoveItems就是当定位到了ITEM节点时,我调用其它的业务处理。因为,人只关注ITEM节点,所以它有一些子节点MAP或子子节点STATE,都在上面一一跳过了。
最后,附上“米”,好“下锅”,注意层次。
<?xml version=”1.0″ encoding=”UTF-8″ ?>
<!– edited with XMLSpy v2013 (http://www.altova.com) by () –>
<LINE ID=”11″ VERSION=”1″>
<FRAME_HEADER>
<ITEM ID=”system_id” LENGTH=”1″ CURPOS=”0″ />
<ITEM ID=”total_length” LENGTH=”2″ CURPOS=”1″ MAX_VALUE=”1025″ />
<ITEM ID=”multi_flag” LENGTH=”1″ CURPOS=”3″ DEFAULT=”0″ />
</FRAME_HEADER>
<FRAME_BODY>
<MESSAGE ID=”NETWORK_ALIVE_STATUS” TYPE=”1″ TRANS=”O2N”>
<ITEM ID=”message_length” LENGTH=”2″ CURPOS=”4″ DESC=”消息长度” MIN_VALUE=”13″ interal_index=”1″ />
<ITEM ID=”time” LENGTH=”4″ CURPOS=”6″ DESC=”时间” FORMAT=”HHMMSS” interal_index=”2″>
<MAP NID=”time” MODE=”1″ SAME=”Y” NINDEX=”2″ KEY=”time|6|4″ DESC=”时间” EX_CODE_KEY=”” />
</ITEM>
<ITEM ID=”version” LENGTH=”2″ CURPOS=”10″ DESC=”版本” DEFAULT=”01H” interal_index=”3″ />
<ITEM ID=”msg_id” LENGTH=”2″ CURPOS=”12″ DESC=”报文ID” interal_index=”4″ />
<CONTENT ID=”data0″ DEFAULT_LEN=”3″>
<ITEM ID=”line_id” LENGTH=”2″ CURPOS=”14″ DESC=”线路号” interal_index=”5″>
<MAP NID=”line_id” MODE=”1″ SAME=”Y” NINDEX=”5″ KEY=”line_id|14|2″ EX_CODE_KEY=”” />
</ITEM>
<ITEM ID=”status” LENGTH=”1″ CURPOS=”16″ DESC=”状态字节:1:代表与当前线路号的信息源(server)连接正常;0:代表断开。” interal_index=”6″>
<MAP NID=”xt_pkg” MODE=”1″ SAME=”N” NINDEX=”6″ KEY=”xt_pkg|16|1″ EX_CODE_KEY=””>
<STATE ID=”11_STATUS_CODE_1″ RAWVALUE=”0x00″ HINT=”通信中断” SAME=”Y”>0x80</STATE>
<STATE ID=”11_STATUS_CODE_2″ RAWVALUE=”0x01″ HINT=”通信正常” SAME=”Y”>0x02</STATE>
</MAP>
</ITEM>
</CONTENT>
</MESSAGE>
<MESSAGE ID=”LOAD_DEVICE_STATUS” TYPE=”1″ TRANS=”N2O”>
<ITEM ID=”message_length” LENGTH=”2″ CURPOS=”4″ DESC=”消息长度” MIN_VALUE=”12″ interal_index=”1″ />
<ITEM ID=”time” LENGTH=”4″ CURPOS=”6″ DESC=”时间” FORMAT=”HHMMSS” interal_index=”2″ />
<ITEM ID=”version” LENGTH=”2″ CURPOS=”10″ DESC=”版本” DEFAULT=”01H” interal_index=”3″ />
<ITEM ID=”msg_id” LENGTH=”2″ CURPOS=”12″ DESC=”报文ID” interal_index=”4″ />
<CONTENT ID=”data0″ DEFAULT_LEN=”2″>
<ITEM ID=”line_id” LENGTH=”2″ CURPOS=”14″ DESC=”线路号” interal_index=”5″ />
</CONTENT>
</MESSAGE>
</MESSAGE>
</FRAME_BODY>
</LINE>
保存和另存,一个TiXmlDocument的SaveFile()函数就搞定了。
生成新的XML时,会用一个api就成了。parent->LinkEndChild(TiXmlNode *);根据不用我解释了吧。加同级,用parent()找父指针嘛。
北京工作居住证攻略
朝阳区人才的位置:三元桥,凤凰城附近
海淀区人才的位置:北京市海淀区西四环北路73号中关村人才发展中心
办理:
首先,你要把自己的证件都复印好,不用等待网络上的信息注册后再准备,但完税证明不要提前,因为有效期只有一个月。
但办这事的入口,还是你公司为你注册了帐号,然后,你就可以登陆并看到办理居住证的链接了。
然后,就是材料最后的准备阶段了,去开完税证明和公司行政打交道完成各种手续。
最后,在提交时,想要办小孩上学要注意随迁问题。住址和居住证跨区的小孩上学问题,需要向学校搞清楚。
年检:
这其实是公司人力的动作,每年四月,他们应该用他们的企业帐号登陆系统,做操作。
续证:
工作居住证到期的前后一个月,要在网上先申请,然后,要去所在区人才,柜台办理。又要拿一大堆打印的申请。
变更:
分公司,住址,随迁等种类变更。但重要的是公司变更吧。
本人下家也具有工作居住证的资质,所以,变更准备材料如下:
(只针对海淀人才)
1)居住证原件(这不用说吧)
2)关于为XXX同志办理《北京市工作居住证》聘用单位变更的申请———-网找模板,加盖公司章
3)聘用单位变更申请———–网找模板,是个人申请,所以不用公章
4)营业执照复印副本
5)离职证明原件+复印件———-注意复印件也要盖章,经办人签字(附句话:经本人同意与原件内容一致)
6)新公司的劳动合同原件+复印件———-注意复印件也要盖章,经办人签字 (附句话: 经本人同意与原件内容一致)
不用每页都有章,最好公司有复印件专用的方章,可以在首页和签字页盖章即可。
说什么诚信声明和进入系统打印申请表,这两项并不需要。
当你的申请被受理后,海淀人才就告诉我,两个月左右,登录看一下系统中办理的状态,如果是完成,那么,你有两个方式来取回自己的居住证。一,让公司人事去办事时顺便取到,二,自己打印一个介绍信,模板不好找,但当时,我把柜台的模板照了下来。这样,可以自己起草一个,找公司盖章,注意只好盖章后,拿这个介绍信才能自己取到。
注销:
也是公司人力的动作,当你想在新公司变更或重新办新的,或其它业务时,前公司应该给你注销先。
注销后,两个月内个人如果没有延期注销的动作,那么你的居住证生命线就over了
延期注销:
当你换的新公司试用期较长,或者暂时没公司,或者工作忙时,可以在注销的两个月最后几天,申请延期注销。
那么你就有了6个月的机动时间。当然,你要登陆系统,自己填写申请并提交。如果你的新公司比较确定,要在备注的内容里体现。据说这样
会不仅有6个月,即使长一些,也能救起证的生命线。提交成功就行,不用去柜台了。
以Qtreeview为例介绍Qt的model/view/item框架
自由行泰国
自由行者干货吐血奉献:
感觉用倒叙的时间串起来可读性高。
行程章节:
健议,6-10天,选2-3地,6天以内,可以专注1城。很多老外一处一呆就是一个月。租车租房租泰妹已成文化,一盘水果一帮朋友喝到深夜。直到出行前,多看穷游攻略,锦囊啥的。没确定机票前,并不需要订太多景点的票和接机出租啥的,前者用app提前一天解决,点对点的接驳在当地解决吧,可以议价嘛。
首先,倒数半年吧,拿护照买亚航票赶打折是必须的,购时要额外去除保险的点选,因为那是默认选中的坑,不要在意big sort的积分,它是事后才积上去的。对于行李和机上餐可按需选择。注意因为是低价机票,所以不包含这些的。
确定了行程,可以细化你每一天的安排了。是一个城市,还是要飞来飞去?由于本人家人5人10天。所以,舍弃了久仰的清迈。因为,考虑到小孩和老人,不能以旅行团一样的安排,所以,曼谷+芭提雅+泰南的苏梅+涛岛,事实证明大家很满意。
曼谷是购物之都,大皇宫父母只呆了不到半小时,就吵着要逛街。所以,在最后两天在曼谷购物,不然,提着大小包去玩可是很辛苦。
芭提雅离曼谷近,大巴2小时,方便随时,并且沿海热闹。并不细说,我老婆最钟爱此地。但并不上岛,因为后面有好戏。
苏梅+岛,四天的深度感受,才能让大家忘记北方的寒冷和帝都的#¥¥%#。
飞前倒数一个半月,去搞定签证,在网上找可信的旅行社带办,一人花费2百多吧。
倒数一周时,换外币,因为换币要提前预约的,不然,很可能白跑一趟,我是在中国银行柜台办理的,据说汇率低。
不用换太多美金,真用不上。甚至不用换。我在华夏卡里存了6K(号称每天第一次取钱免手续费,但好像至少会有50铢会被当地ATM扣)
具体的安排:
华夏存入6K
换美金1K(本人中间有马来西亚的transit,出关玩了半天,所以,其实应该直接换马币)
换泰铢4K
当然,要带信用卡喽
倒数第四天时,下淘宝单,买电话卡,happy-7day卡。虽然,电话功能只用了不超过五次,但随时上网帮了很多的忙。因为,要收发订单邮件的和各种app的使用。7天过期后本人找到服务点,加了两天的上网约110铢
倒数第三天,网上值机,打印登机牌,打印各种订单确认(住宿酒店确认,地址信息等)和地图资源(一般酒店大堂都提供)。把手机的旅行app整理到一个文件夹,下载最新版本,先登陆上所有出游app帐号,以防到时找不到帐号,影响大事。
本人的app介绍如下:(重要程度,由上至下)
google maps
booking.com
面包自由行
穷游
私人邮箱设置
亚航
途牛
携程
蚂蜂窝自由行
前四位很强大,他们会互相配合,这里要赞一下面包。我在面包上订了一个安通海洋公园和一个人妖秀,都是质量很高,前一天下单,第二天享受,当然,要拿确认邮件去享受了。当然有条件的话,可以打印出来。泰国的IT水平不高,找到愿意让你使用的打印机很难的。酒店的服务人员不会同意,因为上网有风险,并且电脑都为公用。而没有像中国一样的打印复印店的。所以,你只能找office了,幸好有好心的人帮助。我转发邮件给他,他打印出来。面包上的景点也都可以关联google导航定位。这样,离的近或打车前去,大可尽在掌握。
再有就是booking.com了,的确专业,对订单反应速度巨快,可以结合苹果的passbook。
文化章节:
喝白酒的人注意,泰国找不到白酒,并且,早餐很难找,因为,上午开店的很少。在寺庙不要吵,也不用交门票。
详细行程一览表:
地点/时间/逗留 | 源–目标机场 | 景点 | 事后总结(有血的教训) |
北京/马来西亚 | PEK—KUL | 马来西亚–双子塔–central park–机场商圈 | 事实上到了central market玩了半天,吃了个饭。有一个30分钟的快轨klia2直达central. |
马来西亚/曼谷 | KUL–DMK | 体验美食,然后休息 | 到达天黑了,入住,准备第二天一早出发芭提雅 |
曼谷/芭提雅 | 坐BTS至下面站之一:1)victoryment station|胜利纪念碑(阿怒烧瓦里拆)2)E7|曼谷市东站|Ekkamai|Eastern Bus Terminal,2号口出就是东站。注:租用面包车.汽车北站(Mo chit) | 四方水上市场另一个响亮名字是杜拉拉水上市场(最好提前网购票)可以坐香蕉船,照相,购物,看表演。中午后人开始多,我们去早了。 | 事实上,酒店前台安排了前往芭提雅的家庭型车,5人一共2000铢 |
巴堤雅 | 原路返曼谷 | 东芭乐园,室内民俗表演,大象表演,骑大象,旅游车参观等。到当地后订房两晚,200人民币一晚,有游泳池,比较舒适。 | 在著名的红灯区街walking street的西北部找了个性价比很高的酒店,记往在海滩的外圈找,那里会便宜。吃海鲜,游泳,逛街(晚上去,你懂的) |
芭提雅/曼谷 | 当地订房一晚,19,200人民币一晚 | 大巴车,坐到离廊曼机场近的站,在那里现找酒店,因为要赶飞机去苏梅,到曼后晚间逛了跳蚤市场,咋都咋(东西很多,但必须狠讲价,比MBK的价水份还大) | |
苏梅岛/20-22 | DMK–NST车船联:大巴–>– Donsak码头->— Lipa Noi Pier(苏梅亚航集合地)–>-面包车->-酒店 |
查汶海滩(Chaweng Beach)、波普海滩(Borphut Beach)、拉迈海滩(Lamai Beach)和湄南海滩(Maenam Beach)。 | 海岛的房间紧张,所以用booking.com早下手了。海难上很热闹,水果很便宜。用面包app订了安通海洋公园,做快艇,浮潜,皮划艇,自助,实在是印象深刻,非常推荐。 |
龟岛(TAO)/23-24 | nakhon si thammarat(NST) –bangkok-Don mueang(DMK)车船联: 酒店–>–Seatran pier->–Donsak pier–>–大巴->-机场-16:10->-FD3187–>-17:30- |
潜水,南苑岛,mahead bea(海滩),购物街很多 | 岛上出租车很贵,要由酒店前台来叫。并且,按地图规划好下车地和游览路线。由于有孩子,不能去南苑岛和潜水。有几个购物区路线。逛的同时,看到了离岛的码头Seatran pier 那里有亚航的接待点,车船联票的入口。 |
龟岛/曼谷/24-26 | DMK–KUL | 大船–7座小巴–飞机 | 一天用来赶路,做大船不用很颠婆。有钱的可以从苏梅飞。 |
曼谷/北京 | KUL–PEK | 唐人街,泰拳,nana街 | 找到大皇宫附近的宾馆住下,第二天路线是,大皇宫,考山路,王权免税店,MBK,克里索普人妖秀。注意,去王权要拿两样东东,护照(本人全程随身)还有是打折地图(免费领于酒店前台,上面有打折卡的)。买的东东可以在机场退税。还有就是湄南河边的人妖秀了。风景和文化大餐。人妖秀很艺术,每个位子送一种自选饮品。第二天,飞京略 |
囧点:
1)买了个超标的箱子,只能托运,而又没买20kg的行李托运,在机场又要登机了,结果高价买了托运–600银子。
2)爸有个小军刀,老婆有些化妆品被安检拦了,幸好,有免费的寄存,等回来北京后,从机场拿走。
3)爸妈先抵泰国机场,对于入境卡拒填,他以为那个是落地签,语言又不通,真是难为他们了。 汇合后出了机场,打不到taxi,因为,机场很规范,有专门的打的通道,要排队,就一定有打表的taxi。
4)上了车,老爸习惯的往副驾驶一座,可是,司机就站在旁边,比划了半天,老爸往前一看,原来有方向盘。
5)注意,泰铢纸币的1K和100的特别相近,本人就大方的给了1K的小费。
6)由于经停马来西亚,本人换了马币,可返程时赶飞机,没有消费掉剩下的钱,结果,回国后发现中国银行不能换马币。结果,留做纪念了。还有若干泰铢硬币。
VS2013字符集小结
VS新版本打开旧项目,即当升级一个vcproject文件时,可能会涉及从“多字节字符集”(可能是utf-8)到unicode字符集的转换。
所以总结一下,代码端如何适应转换。
unicode字符集下,微软引入了一个宽字符集的概念(多讨厌)
所以,有些winapi就是以宽字符集来传参的。
第一类问题:messagebox()函数
所以字符串常量前,加一个L,即L“原来的字符串”;
L的意思是小端序。当为unicode时,长度要么1要么2(汉字),所以,再加上小端序,不会有歧义了。
第二类问题:strcpy()函数要求多字符集,事实此时的CSting已经入乡随俗了用了宽字符集,而直接强制转换就会出现让你头大的提示,
居然const char * 和 CString不等价了。
char SendBuf[512] = {0};
strcpy(SendBuf,strEdit); //CString参数strEdit,报错说不能转换CString到const char *
——————————–
办法一:用新的缓冲区放置,并且必须再转换一下。
char SendBuf[512] = {0};
strcpy(SendBuf,( const char *)strEdit.GetBuffer());
办法二:复杂,此时要做的是把“变质的”CString给救回来。
char SendBuf[512] = {0};
wchar_t temp[512];
MultiByteToWideChar(CP_ACP, NULL, (LPCCH)strEdit.GetBuffer(), 512, temp, 512);
strcpy(SendBuf,(const char *)temp);
m_Conn.Send(SendBuf,strlen(SendBuf));
第三类问题,atoi转int:
把atoi换成_ttoi即可,这是神器,在啥字符集下,都可编译。
第四类问题,CString->std::string 举例如下:
CString strMfc=“test“;
std::string strStl;
#ifdef _UNICODE
USES_CONVERSION
strStl=W2A(strMfc.LockBuffer());
strMfc.UnlockBuffer();
#else
strStl = strMfc.GetBuffer(0);
strMfc.ReleaseBuffer();
#endif
—————-
有时,CString可以做为桥梁,把乱码的UTF-8字符串转成string打印正确。思路是先用下面的函数转换乱码,再把返回的CString转string.
CString UTF8toUnicode(const char* utf8Str, UINT length)
{
CString unicodeStr;
unicodeStr = _T(“”);
if (!utf8Str)
return unicodeStr;
if (length == 0)
return unicodeStr;
//转换
WCHAR chr = 0;
for (UINT i = 0; i
BSTR bstrTest = ::SysAllocString(L”Test”);
_bstr_t bstr_t(bstrTest);
std::strStl = bstr_t;
SysFreeString(bstrTest );
std::string -> BSTR 举例如下
std::string name = “nisb”;
_bstr_t bstr_t(name.c_str());
BSTR ret_val = bstr_t.GetBSTR();
————————————————-
转来一篇原理编码的原理:
1:使用CString,要包含文件afx.h,比如在Win32 Console Application中Alt+F7选择Use MFC in a Static Liberary,然后再添加#include
2:WCHAR ch = L’中’;与CHAR ch = ’中’;的区别是第一种使用UNICODE编码,第二种方式一般不经常用到,比如:
WCHAR strA [ 2 ] = { L’中’ , 0 } ;//打开VC的Options菜单,选中Debug选项卡中的Display unicode strings后,可以看到strA的值。
WCHAR strB [ 2 ] = { ‘中’ , 0 } ;
CString strC ;
strC+ = ( ( char * ) strB ) [ 1 ] ;
strC+ = ( ( char * ) strB ) [ 0 ] ;//strC==”中”
3:CString的AllocSysString ( )成员函数;可以方便的把一个字符串转换成UNICODE形式。记得使用完该UNICODE字符串后要调用::SysFreeString()函数释放字符串。
4: CString::AllocSysString ( )或者::SysAllocString得到的字符串并不是普通的UNICODE字符串,它之前的四个字节会存放申请的字符串的长度:
CString strD = ”asdf”;
BSTR strD = strC.AllocSysString( ) ;
long i =* ( ( long * ) strD – 1 ) ; // i == 8;一个UNICDE字符的长度是2字节,所以strD的长度为8个字节。
4:UTF-8码转换为一般的字符串:
#include ” Windows.h ”
int main(void)
{
char str [ 256 ] = {( char )0xE4, ( char ) 0xBD, ( char ) 0xA0, ( char ) 0xE5 ,
( char)0xA5 ,(char)0xBD, (char)0x61, (char)0x62 ,(char)0x63,(char)0} ; //一段UTF-8编码
WCHAR* strA;
int i= MultiByteToWideChar ( CP_UTF8 , 0 ,(char*) str ,-1 ,NULL,0);
strA = new WCHAR[i];
MultiByteToWideChar ( CP_UTF8 , 0 ,( char * ) str, -1, strA , i );
i= WideCharToMultiByte(CP_ACP,0,strA,-1,NULL,0,NULL,NULL);
char *strB=new char[i];
WideCharToMultiByte (CP_ACP,0,strA,-1,strB,i,NULL,NULL);
//strB即为所求
delete []strA;
delete []strB;
return 0;
}
5:在转换方面_bstr_t是最最灵活的,他提供了UNICODE到一般字符串的直接转换:
#include
_bstr_t strA;
char *strB=”中国人”;
strA=strB;
WCHAR *strC=strA;
long i =* ( ( long * ) strC – 1 ) ;// i 亦是字符串的字节长度
char *strD=strA;
return 0;
宽窄字串转换!
两种方法:1、CString 2、_bstr_t
#include “comutil.h”
//注意在Project-》Setting-》Link中加入comsupp.lib,从而使_bstr_t可用
void CAaaDlg::OnButton1()
{
// TODO: Add extra cleanup here
_bstr_t a(L”sdfsafds”);
a+=”zzz”;
char * b = (char *)a;//获得内部BSTR的char*指针,勿做修改和释放
WCHAR *c=(WCHAR *)a;//获得内部BSTR的WCHARr*指针,勿做修改和释放
CString p = L”asdfsa”;
p+=”ppp”;
WCHAR *y =p.AllocSysString(); //获得WCHAR*指针,使用完请释放,否则有内存泄漏。
char *z = p.GetBuffer(p.GetLength()+1);//内部Buffer指针,z不要释放
::SysFreeString(y);
}
.net应用odp.net小记
一,下载ODAC112040Xcopy_64bit并解压,在OTP里找。
在cmd中执行>install.bat odp.net4 d:\driver4oracle11.2 odac
odp.net4————你想部署的driver,本人使用.netframework4,不是asp.net和.net2,所以,没用使用All和指定的其它选项。
d:\driver4oracle11.2————你要部署的目标客户机的oracle_home,当然在windows下就加入它到系统环境变量path中。
odac————当在同目录有多个driver时,可以区别吧,反正,因为加了它,可能会报错。但不影响使用。
[true]———-可选的,默认值,即把odp.net依赖的instantclient安装,当你加false时,不装依赖且考虑和已经存在的新版本oracle或现有的环境配合。
当执行了上面的命令后,instantclient(即被odp.net依赖的)也一并从压缩包中被抽取,拷安装到了oracle_home目录中。
二,然后就是设置tnsnames.ora文件。从服务端上相应位置拷过来,放置到home目录中。顺便执行下*access.dll同目录中的oraprovcfg.exe,它是用于注册系统环境变量的。虽然上面已经配置好了,多来一次也无妨。
三,开始客户端程序的开发吧,把home路径中的Oracle.DataAccess.dll拷到项目的debug,和exe同级下面,并在VS中引用,加入using行:
using Oracle.DataAccess.Client;
using Oracle.DataAccess.Types;
代码示例:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Oracle.DataAccess.Client;
using Oracle.DataAccess.Types;
namespace odp
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private string strConn = “Data Source=(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = ohala-PC)(PORT = 1521))(CONNECT_DATA = (SERVER = DEDICATED)(SERVICE_NAME = XE)));”+
“User id=JINGHU;Password=JINGHU;” ;
public void initDBConn()
{
try
{
using(OracleConnection objConn = new OracleConnection(strConn))
{
objConn.Open();
string strSQL = “select * from V_TM_SEGMENT_CFG where SEGMENT_CODE=10 order by STATION_SEQUENCE,TRACK_CODE”;
using(OracleDataAdapter objAdapter = new OracleDataAdapter(strSQL,objConn))
{
//
DataSet ds = new DataSet();
objAdapter.Fill(ds);
dataGridView1.DataSource = ds.Tables[0];
//dataGridView1.
dataGridView1.Show();
}
//using (OracleCommand objCommand = new OracleCommand(strSQL, objConn))
//{
// using(OracleDataReader objReader = objCommand.ExecuteReader())
// {
// while (objReader.Read())
// {
// Console.WriteLine(“segment_code is :” + objReader[0].ToString() + “;station_code is :” + objReader[1].ToString());
// //dataGridView1.DataSource
// }
// }
//}//command
}
} catch(Exception ex)
{
}
}
private void button1_Click(object sender, EventArgs e)
{
initDBConn();
}
}
}
升级win10备忘
首先,接手电脑为win8.1,高兴去在线升级结果发现将会升级成win10家庭版,果断拒绝换路。
然后,策略再选择成把win8.1变成专业版,再online升级,如果再不行,就使用ISO了,( VK7JG-NPHTM-C97JM-9MPGT-3V66T)win10密钥吧。
1)升8再升10
保守治疗先,继续玩win8.1,右键“这台电脑”,在系统属性界面,选 择“获取新版本的Windows的更多功能”或者在控制面板中应该不难找到“向windows8.1添加功能”,然后,又是要输入产品密钥。
在这一步输入专业版的零售密钥,如果是升级到win8专业版,就输入8GDW2-NHD3Y-C79G4-B82C4-6Q4DH,(用的这个)
如果是升级到win8.1专业版,就输入 29NQY-3TDJ2-CPXXD-CHDMY-CWD2Y。
然后,漫长的等待windows update进度。注意,要确认本机是已经被激活的不然会升级不成功,并且是最后才给你结果,说不成功。当然如果是激活的,那么就关闭360,再重启。(本人采用方式)
2)ISO升10
直接点击ISO,win10不用虚拟光驱了,又一群要下岗的同行。但这样安装上的win10可能会出现问题。
3)ISO装10(或者用老毛桃啥的做个U盘,引导安装)
过程中选择不保留原有应用和个人文件夹等,那就没有以前版本的windows,回退都没有路子。
程序员的自我修养
四大神器,解决依赖:
ldd是用来查看执行文件或.a,.so的依赖关系利器(从链接的角度)。
nm———————查看静态符号表,观察依赖关系
-sD *.so
objdump -p t_sql.o | grep NEEDED
库命令:
file *.o—————看ELF信息
objdump -[看列表] *.o——看目标文件的结构和内容
基本信息(-h)
更多信息(-x)
依赖信息(-p)objdump -p t_sql.o | grep NEEDED
动态链接的可执行文件中包括got,有时有调用别模块时的共享对象也存在此段。
查看一个so是否PIC(地址无关性)编译的:
readelf -d .so | grep TEXTREL
如果有输出,用的是装载时重定位(虽多进程调用可以,但牺牲了效率),否则,证明编译时加了-fPIC,是地址无关。
readelf—————-看elf详细信息,包括(系统位,大小端,是否可执行)
文件头信息(-h)
详细的信息(-S)较权威的段表信息
从linker角度来查看链接器使用的dynamic段的信息(-d *.so)链接库的elf信息,同于ldd(宏观模块体现)。
-sD *.so查看动态符号表(从库提供服务或使用的角度),针对段.dynsym观察依赖关系
-l ../bin/devcomm | grep interpreter(链接器使用的段)查看生成它的链接器(可执行文件)
-r *.so查看重定向符号表
链接的秘密:
目标文件静态重定向—动态链接文件重定向——可执行动态链接文件重定向
rel.text——————rel.dyn———–针对数据引用,修正位于数据段中的got(全局变量的引用地址)
rel.data——————rel.plt————针对函数引用,修正got.plt
全局符号表
二元信号量:
信号量(多元):
互斥量:不同于二元信号量:哪线程存得,哪线程释放
相同二元信号量:都是约束线程排队的
临界区:在一点处与互斥量不同:其它进程不可见。(和内核对象名称不太相符)
条件变量:同时阻塞和唤醒多个线程
静态编译Qt5.5并应用成果
一直为打包Qt开发的东东依赖库发愁。只好研究下静态编译,当然选个最新的版本。
环境如下:
win7 x86
VS2012
perl5.16.2
python34(32bit)
ruby21
Qt5addin1.2.4
说明:ruby安装时要把三个都选择上,QT5addin插件安装要特有耐心,不然总会觉得,程序假死了。(后来发现是装集成help文档时占时间,可以不装它的)
以上安装在一个独立的虚机,方便以后改造,重要的一点是,一编译就2-3个小时,你对着屏发呆嘛?
下载Qt5.5的源码,进入其目录,需要改的有两处:
<src目录>\qtbase\mkspecs\win32-msvc2012\qmake.conf.
将
将以下三处 -MD修改为 -MT
QMAKE_CFLAGS_RELEASE = -O2 -MT
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -O2 -MT -Zi
QMAKE_CFLAGS_DEBUG = -Zi -MTd
当环境不同,聪明的你会找到需要更改的位置。5.5源码包是mkspecs/comon/msvc-desktop.conf里面改。
建立个批处理文件,如vs2012.build.bat
内容如下:
::配置路径
set QT5_DIR=C:\qt_tool\qt-everywhere-opensource-src-5.5.0-alpha
set THIRDPARTY_DIR=C:\qt_tool\Build
::如果您用mingw可以在这儿设置下您的mingw目录
set PATH=%PATH%;C:\Perl\site\bin;C:\Perl\bin;C:\Python34;C:\Ruby21\bin;
set PATH=%PATH%;%QT5_DIR%\bin;%QT5_DIR%\qtbase\bin;%QT5_DIR%\gnuwin32\bin;
::配置依赖,mingw的可能需要您手动加上库和头文件位置,vs的话您可以打开相应的VS* X86/64 本机命令提示符
::set SQLITE3SRCDIR=%THIRDPARTY_DIR%\sqlite
::set LIB=%LIB%;%THIRDPARTY_DIR%\icu\win32\lib;%THIRDPARTY_DIR%\icu\win32\libs;%THIRDPARTY_DIR%\openssl\openssl32\lib
::set INCLUDE=%INCLUDE%;%THIRDPARTY_DIR%\icu\win32\include;%THIRDPARTY_DIR%\openssl\openssl32\include
::set PATH=%PATH%;%THIRDPARTY_DIR%\icu\win32\bin;%THIRDPARTY_DIR%\openssl\openssl32\bin
::配置QT,为了在输入configure配置qt编译选项,我就直接写到bat了、、、
cd %QT5_DIR%
configure -prefix C:\QtSdk\Win32_static -opensource -confirm-license -static -platform win32-msvc2012 -release -c++11 -qt-sql-sqlite -qt-zlib -qt-libpng -qt-libjpeg -qt-freetype -no-angle -no-icu -opengl desktop -nomake examples -nomake tests -no-compile-examples -skip qtwebkit
把它保存。不提倡改那个bat文件,因为,webkit是不能静态编译的,并且它很耗时,并且很多选项都是经验之谈。
然后,找nmake去。在开始菜单里找”vs2012 x86本机工具命令指示行“,
打开,进入源码目录,执行批处理。
你的环境一致,定能configure过。注意,要清除前一次的垃圾,需要用nmake distclean
后面的事就是敲nmake,泡杯茶了。
有时,你真的nmake成功了,但是不一定能nmake install正常。但我坚信install只是一系列拷贝操作。你要的那些lib已经OK了,你可以部署的时候再用他们。
当然,你可以坚持找原因,nmake install成功。
注意,不要轻易改变源码的位置,或节省空间删除它。否则,上帝保佑你。
后记:
以为装了Qt5addin,打开就可以看到Qt5的菜单,错了,还要真的装个Qt sdk才行。
Qtcreator静态编译了一下,的确可用,但是无法部署到同为32的xp下。可能是因为,Qt使用的编译器仍然是VS2012的,所以,再用VS2012+Qt5addin试一次,何况这是我们目标。
不过,我发现一个坑,Qt5addin1.2.4根本和VS2012不兼容,而且这不会提示你。
1.2.3装后,开始真正的应用静态编译的成果了。
项目设置:
为了让exe能跑在xp上,需要设置在工程—-属性—配置属性–常规–平台工具集v110_xp
因为,我编译的lib都是realse的,所以把项目设成realse
改成(release为MT,debug为MTD)
在工程—-属性—配置属性—c/c++—代码生成—-运行库
选择为“多线程(/MT)”
这样设置可能是约定了对lib的调用方式。
否则,编译时报错:runtimelibrary
error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MT_StaticRelease”不匹配值“MD_DynamicRelease”
在工程—-属性—配置属性—链接器
本人的附加依赖项(备忘):$(QTDIR)\lib\Qt5Core.lib;$(QTDIR)\lib\Qt5Gui.lib;$(QTDIR)\lib\qtmain.lib;$(QTDIR)\lib\Qt5Widgets.lib;$(QTDIR)\plugins\platforms\qwindows.lib;$(QTDIR)\lib\Qt5PlatformSupport.lib;$(QTDIR)\plugins\platforms\qminimal.lib;$(QTDIR)\plugins\platforms\qoffscreen.lib;$(QTDIR)\lib\Qt5OpenGL.lib;$(QTDIR)\lib\Qt5OpenGLExtensions.lib;$(QTDIR)\lib\Qt5Sql.lib;winspool.lib;shlwapi.lib;rpcrt4.lib;$(QTDIR)\plugins\imageformats\qico.lib;$(QTDIR)\plugins\imageformats\qsvg.lib;$(QTDIR)\lib\Qt5Qml.lib;$(QTDIR)\lib\Qt5Quick.lib;comdlg32.lib;oleaut32.lib;imm32.lib;winmm.lib;glu32.lib;opengl32.lib;gdi32.lib;$(QTDIR)\lib\qtharfbuzzng.lib;kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;mpr.lib;%(AdditionalDependencies)
上面配置解决了一个ub_buffer_create……destroy啥的编译错误。
QT5设置:
VS中设置好Qt versions为静态的sdk,然后在Qt project setting—–properties页的最后一个设置上。
即version属性选择下拉中的静态sdk(有时忘记它,其实主要开关在这里)
最后构建你的程序吧。不过还是有坑的。虽然没有报error了,但当你运行它会提示你:
……Failed to load platform plugin windows……
这次改main.cpp吧
#include
Q_IMPORT_PLUGIN (QWindowsIntegrationPlugin);
编译通过,这次把exe放到没有Qt5安装的xp下,都如愿运行,出画面了。
大胆的写Qt吧,一次编写,到处部署(很方便)