??xml version="1.0" encoding="utf-8" standalone="yes"?>一本综合久久国产二区,久久精品成人欧美大片,国产福利电影一区二区三区久久老子无码午夜伦不 http://www.shnenglu.com/Squirrel/始有道,道生时空。时I,~程之阴队뀂不得道者失时空Q得道者时I盈余以完工。其有异乎?zh-cnWed, 07 May 2025 03:17:17 GMTWed, 07 May 2025 03:17:17 GMT60Windowspȝ性能监视?/title><link>http://www.shnenglu.com/Squirrel/archive/2006/05/21/7458.html</link><dc:creator>Squirrel</dc:creator><author>Squirrel</author><pubDate>Sun, 21 May 2006 03:41:00 GMT</pubDate><guid>http://www.shnenglu.com/Squirrel/archive/2006/05/21/7458.html</guid><wfw:comment>http://www.shnenglu.com/Squirrel/comments/7458.html</wfw:comment><comments>http://www.shnenglu.com/Squirrel/archive/2006/05/21/7458.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/Squirrel/comments/commentRss/7458.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/Squirrel/services/trackbacks/7458.html</trackback:ping><description><![CDATA[   最q看到浪潮的猎鹰服务器管理YӞ其中可以对远E服务器的CPU和内存用率q行实时监视Q就像Q务管理器那样l制一个报表。我推断他要么是使用SNMP协议从客h拿到数据之后在传递给理器,要么是使用Windows提供的某些System Performence COMlg来抓数据?br />   查MSDNQ上有一个System Monitor的例子。居然是用VBScript来调一调控刉?〉管理工?〉性能-〉系l监视器。既然是用HTML嵌VBScriptQ那转换为应用程序到也方便,文件后~名改?htaQ即以HTML Application方式打开Q由MSHTA.exe来解释执行就可以了?br />   下面的程序就是从命o行中获取要监视的计算机IP地址后,启动System MonitorQ监视之?br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">HTML</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br /><img src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">HEAD</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br /><img src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">HTA:APPLICATION </span><span style="COLOR: #ff0000">ID</span><span style="COLOR: #0000ff">="oHTA"</span><span style="COLOR: #ff0000"><br /><img src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" align="top" />    APPLICATIONNAME</span><span style="COLOR: #0000ff">="myApp"</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br /><img src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" align="top" />   </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">meta </span><span style="COLOR: #ff0000">http-equiv</span><span style="COLOR: #0000ff">="Content-Type"</span><span style="COLOR: #ff0000"> content</span><span style="COLOR: #0000ff">="text/html; charset=gb2312"</span><span style="COLOR: #ff0000"> </span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br /><img src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" align="top" />   </span><span style="COLOR: #0000ff"></</span><span style="COLOR: #800000">HEAD</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br /><img src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">BODY </span><span style="COLOR: #ff0000">BGCOLOR</span><span style="COLOR: #0000ff">="#C0C0C0"</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_210_297_Open_Image" onclick="this.style.display='none'; Codehighlighter1_210_297_Open_Text.style.display='none'; Codehighlighter1_210_297_Closed_Image.style.display='inline'; Codehighlighter1_210_297_Closed_Text.style.display='inline';" src="http://www.shnenglu.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_210_297_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_210_297_Closed_Text.style.display='none'; Codehighlighter1_210_297_Open_Image.style.display='inline'; Codehighlighter1_210_297_Open_Text.style.display='inline';" src="http://www.shnenglu.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />        </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">SCRIPT </span><span style="COLOR: #ff0000">LANGUAGE</span><span style="COLOR: #0000ff">="VBScript"</span><span style="COLOR: #0000ff">></span><span id="Codehighlighter1_210_297_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.shnenglu.com/images/dot.gif" /></span><span id="Codehighlighter1_210_297_Open_Text"><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"><br /><img src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" align="top" />  </span><span style="COLOR: #0000ff; BACKGROUND-COLOR: #f5f5f5">Sub</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> Monitor_OnCounterAdded(index)<br /><img src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" align="top" />    Monitor.Counters.Item(</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">1</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">).Width </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">=</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">8</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"><br /><img src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" align="top" />  </span><span style="COLOR: #0000ff; BACKGROUND-COLOR: #f5f5f5">End Sub</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"><br /><img src="http://www.shnenglu.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />        </span></span><span style="COLOR: #0000ff"></</span><span style="COLOR: #800000">SCRIPT</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br /><img src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">OBJECT </span><span style="COLOR: #ff0000">CLASSID</span><span style="COLOR: #0000ff">="clsid:C4D2D8E0-D1DD-11CE-940F-008029004347"</span><span style="COLOR: #ff0000"> ID</span><span style="COLOR: #0000ff">="Monitor"</span><span style="COLOR: #ff0000"> HEIGHT</span><span style="COLOR: #0000ff">="80%"</span><span style="COLOR: #ff0000"> WIDTH</span><span style="COLOR: #0000ff">="100%"</span><span style="COLOR: #ff0000"><br /><img src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" align="top" />            VIEWASTEXT</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br /><img src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff"></</span><span style="COLOR: #800000">OBJECT</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_467_1402_Open_Image" onclick="this.style.display='none'; Codehighlighter1_467_1402_Open_Text.style.display='none'; Codehighlighter1_467_1402_Closed_Image.style.display='inline'; Codehighlighter1_467_1402_Closed_Text.style.display='inline';" src="http://www.shnenglu.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_467_1402_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_467_1402_Closed_Text.style.display='none'; Codehighlighter1_467_1402_Open_Image.style.display='inline'; Codehighlighter1_467_1402_Open_Text.style.display='inline';" src="http://www.shnenglu.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />        </span><span style="COLOR: #0000ff"><</span><span style="COLOR: #800000">SCRIPT </span><span style="COLOR: #ff0000">LANGUAGE</span><span style="COLOR: #0000ff">="VBScript"</span><span style="COLOR: #0000ff">></span><span id="Codehighlighter1_467_1402_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.shnenglu.com/images/dot.gif" /></span><span id="Codehighlighter1_467_1402_Open_Text"><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"><br /><img src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" align="top" />        <br /><img src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" align="top" />  </span><span style="COLOR: #0000ff; BACKGROUND-COLOR: #f5f5f5">Sub</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> Window_OnLoad<br /><img src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff; BACKGROUND-COLOR: #f5f5f5">On</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> </span><span style="COLOR: #0000ff; BACKGROUND-COLOR: #f5f5f5">Error</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> </span><span style="COLOR: #0000ff; BACKGROUND-COLOR: #f5f5f5">Resume</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> </span><span style="COLOR: #0000ff; BACKGROUND-COLOR: #f5f5f5">Next</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"><br /><img src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" align="top" />    Monitor.ShowValueBar </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">=</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> </span><span style="COLOR: #0000ff; BACKGROUND-COLOR: #f5f5f5">True</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"><br /><img src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" align="top" />    Monitor.ShowHorizontalGrid </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">=</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> </span><span style="COLOR: #0000ff; BACKGROUND-COLOR: #f5f5f5">True</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"><br /><img src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" align="top" />    <br /><img src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" align="top" />    Arg </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">=</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> </span><span style="COLOR: #0000ff; BACKGROUND-COLOR: #f5f5f5">Trim</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">( oHTA.commandLine )<br /><img src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" align="top" />    IPArgPos </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">=</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> </span><span style="COLOR: #0000ff; BACKGROUND-COLOR: #f5f5f5">InStr</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">(</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">2</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">, Arg, </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">""</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">, </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">1</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">)<br /><img src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" align="top" />    IPArg </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">=</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> </span><span style="COLOR: #0000ff; BACKGROUND-COLOR: #f5f5f5">Trim</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">( </span><span style="COLOR: #0000ff; BACKGROUND-COLOR: #f5f5f5">right</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">( Arg, </span><span style="COLOR: #0000ff; BACKGROUND-COLOR: #f5f5f5">len</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">(Arg)</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">-</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">IPArgPos) )<br /><img src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" align="top" />    <br /><img src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" align="top" />    IPStrings </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">=</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> </span><span style="COLOR: #0000ff; BACKGROUND-COLOR: #f5f5f5">split</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">( IPArg, </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">, </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">-</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">1</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">, </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">1</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> )<br /><img src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff; BACKGROUND-COLOR: #f5f5f5">for</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> i </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">=</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">0</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> </span><span style="COLOR: #0000ff; BACKGROUND-COLOR: #f5f5f5">to</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> </span><span style="COLOR: #0000ff; BACKGROUND-COLOR: #f5f5f5">uBound</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">(IPStrings)<br /><img src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" align="top" />    Monitor.Counters.Add( </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">\\</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">+</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> IPStrings(i) </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">+</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">\Processor(_Total)\% Processor Time</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> )<br /><img src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" align="top" />    Monitor.Counters.Add( </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">\\</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">+</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> IPStrings(i) </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">+</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">\Memory\Available MBytes</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> )<br /><img src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" align="top" />    Monitor.Counters.Add( </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">\\</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">+</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> IPStrings(i) </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">+</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">PhysicalDisk(_Total)\Avg. Disk Queue Length</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> )<br /><img src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" align="top" />    Monitor.Counters.Add( </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">\\</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">+</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> IPStrings(i) </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">+</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">\LogicalDisk(_Total)\% Free Space</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> )<br /><img src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" align="top" />    Monitor.Counters.Add( </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">\\</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">+</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> IPStrings(i) </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">+</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">\Network Interface(*)\Bytes Total/sec</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> )<br /><img src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff; BACKGROUND-COLOR: #f5f5f5">Next</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"><br /><img src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #008000; BACKGROUND-COLOR: #f5f5f5">'</span><span style="COLOR: #008000; BACKGROUND-COLOR: #f5f5f5">Monitor.Counters.Add( "\Process(*)\% Processor Time")</span><span style="COLOR: #008000; BACKGROUND-COLOR: #f5f5f5"><br /><img src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">    Monitor.DisplayType</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">=</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">sysmonLineGraph<br /><img src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" align="top" />    Monitor.GraphTitle</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">=</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> </span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">计算机系l性能监视</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"><br /><img src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" align="top" />  </span><span style="COLOR: #0000ff; BACKGROUND-COLOR: #f5f5f5">End Sub</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"><br /><img src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" align="top" />  <br /><img src="http://www.shnenglu.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />        </span></span><span style="COLOR: #0000ff"></</span><span style="COLOR: #800000">SCRIPT</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br /><img src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff"></</span><span style="COLOR: #800000">BODY</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br /><img src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff"></</span><span style="COLOR: #800000">HTML</span><span style="COLOR: #0000ff">></span><span style="COLOR: #000000"><br /><img src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" align="top" /></span></div>   不知道大家有没有使用qCOMlg这L东西嵌到C++E序中。如果有的话Q不妨发表上来看看?img src ="http://www.shnenglu.com/Squirrel/aggbug/7458.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/Squirrel/" target="_blank">Squirrel</a> 2006-05-21 11:41 <a href="http://www.shnenglu.com/Squirrel/archive/2006/05/21/7458.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Windows凭据理http://www.shnenglu.com/Squirrel/archive/2006/05/20/7445.htmlSquirrelSquirrelSat, 20 May 2006 11:54:00 GMThttp://www.shnenglu.com/Squirrel/archive/2006/05/20/7445.htmlhttp://www.shnenglu.com/Squirrel/comments/7445.htmlhttp://www.shnenglu.com/Squirrel/archive/2006/05/20/7445.html#Feedback0http://www.shnenglu.com/Squirrel/comments/commentRss/7445.htmlhttp://www.shnenglu.com/Squirrel/services/trackbacks/7445.html   在Windows XP和Server 2003 中都已存在了“存储的用户名和密码”。在XP中,通过控制面板中的用户帐户-〉选择用户-〉管理我的网l密码。而在Server 2003中,则在控制面板下直接有“存储的用户名和密码”项?br />   我们调用一些APIQ如WTSOpenServerQQueryServiceStatusQNetUserEnum{等涉及到RPC的,只要当前用户存储有目标远E机的权限合适的凭据Q则q些API׃会因产生ERROR_ACCESS_DENIED而执行失败。因为我q不Windows的底层是如何q行控制的,比如Q是否调用了SSPIQ所以,执行q些APIӞ我只能向用户要管理员口o。但又不可能每次都让用户去输入一遍用户名和密码,那么Q也需要保存密码?br />   既然保存了密码,必考虑删除密码Q那么密码管理的问题也就来了。说到密码管理,我在前些q看电视的时候,看到介绍一个叫什么“网l螃蟹”的|站Q他是专门提供个h密码理的,当时我就惻I有h会去把自q密码交给别h打理吗?q好像不大可能。何来也没听到什么网l螃Ҏ行的消息?br />   现在我的目中,如果用户有了一台机器(PCQ的密码Q那么,他就有了N台服务器的管理员权限。这当然是不被允许的了。怎么办?
   找了一些APIQ是Authentication Functionspd的。于是,下面一个小实验代码是x枚D用户凭据的?br />
#include <windows.h>
#include 
<WinCred.h>
int main(){

  DWORD dwCount 
= 0;
  PCREDENTIAL 
* pCredArray = NULL ;

  
if( CredEnumerate( NULL, 0&dwCount, &pCredArray ) ){

    
for( DWORD dwIndex = 0; dwIndex < dwCount; dwIndex++){
      PCREDENTIAL pCredential 
= pCredArray[dwIndex];

      cout 
<< "*********************************\r\n";

      cout
<<  "Flags: " << pCredential->Flags << "\n"
          
<<  "Type:  " <<  pCredential->Type << "\n"
          
<<  "Name:  " << pCredential->TargetName << "\n"
          
<<  "Persist: "<< pCredential->Persist  <<  "\n"
          
<<  "User:  " <<  pCredential->UserName <<  "\n";

      cout 
<< "Data:  \r\n";

      
char szHexBuffer[256= "";
      
char szAsciiBuffer[256= "";
      
char szHex[16];
      
char szAscii[2];
      DWORD dwByte;

      
for (dwByte = 0; dwByte < pCredential->CredentialBlobSize; dwByte++)
      
{
        BYTE byte1 
= pCredential->CredentialBlob[dwByte];
        sprintf(szHex, 
"%2.2X ", byte1);
        szAscii[
1= '\0';

        
if (byte1 >= 32 && byte1 < 128)
          szAscii[
0= (UCHAR)byte1;
        
else
          szAscii[
0= ' ';

        strcat(szHexBuffer, szHex);
        strcat(szAsciiBuffer, szAscii);

        
if (dwByte == pCredential->CredentialBlobSize - 1 
          
|| dwByte % 16 == 15)
        
{
          printf(
"%-50s %s\r\n", szHexBuffer, szAsciiBuffer);
          szHexBuffer[
0= '\0';
          szAsciiBuffer[
0= '\0';
        }


      }


      cout 
<< "*********************************\r\n";

    }


    CredFree( pCredArray );
  }

  
//system( "rundll32 keymgr.dll,KRShowKeyMgr");
  return 0;
}

   好像凭据数据q没能打出来?br />
   后来Q本着“编E的最高境界就是不~程”的_Q我惻I如果直接把Windows的那个“存储的用户名和密码”对话框调出来用用不也可以吗。用ProcessExplorerQ找C个叫keymgr.dll的东西,嗯,估计对话框就在里面?br />   在“运行”中输入“control keymgr.dll”或“rundll32 keymgr.dll,KRShowKeyMgr”,对话框就出来了?br />   又省事了Q?img src ="http://www.shnenglu.com/Squirrel/aggbug/7445.html" width = "1" height = "1" />

Squirrel 2006-05-20 19:54 发表评论
]]>
如此目理http://www.shnenglu.com/Squirrel/archive/2006/05/19/7410.htmlSquirrelSquirrelFri, 19 May 2006 07:56:00 GMThttp://www.shnenglu.com/Squirrel/archive/2006/05/19/7410.htmlhttp://www.shnenglu.com/Squirrel/comments/7410.htmlhttp://www.shnenglu.com/Squirrel/archive/2006/05/19/7410.html#Feedback0http://www.shnenglu.com/Squirrel/comments/commentRss/7410.htmlhttp://www.shnenglu.com/Squirrel/services/trackbacks/7410.html   q几天因Z个项目的事情非常郁闷。本来从底层到界面辛辛苦苦地写了两个月的东西Q等到第一个版本发布之后,所谓的目l理居然以ؓ大功告成Q说剩下的只是维护?br />    作ؓ一个项目经理,对程序员开发的产品都不了解Q也q了,你搞好你的进度控Ӟ作好与其他部门之间的接口Q那也不错。可是这位仁兄还要不时地q预技术上面的事情。按照他的写Linux字符命o界面E序的思\来指挥Windows囑ŞE序的设计。一切都所谓的“简单”。要知道Q简单是对用戯言的,对程序员来说Q简单的设计不能解决所有的问题。不要把Linux下U所谓的而简单而“强悍”的工具可以解决所有需求的思想来指导针对Windows用户的设计!
更搞W的是,当我提出E序中有要修改的地方Qƈ询问主要寚w些方面进行优化时Q他居然提出你们的Q务就是把现在的代码压?万行以下Q现在代码行Cؓ1?左右Q!其理由是便于理Q!我真是哭W不得,我不知道大家是否遇到q种样子的项目经理。有q样理软g开发的吗?Q!
   更气人的是,当我向他提出修改意见Qƈ实现一些前期设计因q度问题而砍掉的亮点功能Ӟ他犹豫了一下,然后_你们先学习吧Q(所谓的学习不过是个q子Q就是让你闲着。我来公总来就没有什么培训!Q?br />   靠,食君之禄Q忠君之事。我来公司是做事来的Q不是TMD休息Q疗养,{死来的Q是可忍Q孰不可忍?Q?br />   估计国内的小企业Q特别是Y件企业都一个样Q找几个人写点代码,然后去骗国Ӟ骗老百姓的钱,到手之后Q就把这几个E序员一扔,他才不考虑什么h力资源的问题呢?br />骗子Q?/p>


 



Squirrel 2006-05-19 15:56 发表评论
]]>
~程语言发展历程http://www.shnenglu.com/Squirrel/archive/2006/05/16/7252.htmlSquirrelSquirrelTue, 16 May 2006 05:52:00 GMThttp://www.shnenglu.com/Squirrel/archive/2006/05/16/7252.htmlhttp://www.shnenglu.com/Squirrel/comments/7252.htmlhttp://www.shnenglu.com/Squirrel/archive/2006/05/16/7252.html#Feedback0http://www.shnenglu.com/Squirrel/comments/commentRss/7252.htmlhttp://www.shnenglu.com/Squirrel/services/trackbacks/7252.html

Squirrel 2006-05-16 13:52 发表评论
]]>
Windows?ACE中的地址重用http://www.shnenglu.com/Squirrel/archive/2006/05/15/7215.htmlSquirrelSquirrelMon, 15 May 2006 10:51:00 GMThttp://www.shnenglu.com/Squirrel/archive/2006/05/15/7215.htmlhttp://www.shnenglu.com/Squirrel/comments/7215.htmlhttp://www.shnenglu.com/Squirrel/archive/2006/05/15/7215.html#Feedback2http://www.shnenglu.com/Squirrel/comments/commentRss/7215.htmlhttp://www.shnenglu.com/Squirrel/services/trackbacks/7215.html
   我所遇到q的问题是在ACE_SOCK_Dgram_Bcast的第4个构造参数reuse_addr赋gؓ1Q但很遗憾,在Windowsq_上,是不能使端口重用生效。用setsockopt来强制服用端口,仍然无效Q用ACE_SOCK_Dgram也试q了Q同h效。ACE的代码中如是_

// If we are using winsock2 then the SO_REUSEADDR feature is broken
// SO_REUSEADDR=1 behaves like SO_REUSEPORT=1. (SO_REUSEPORT is an
// extension to sockets on some platforms)
// We define SO_REUSEPORT here so that ACE_OS::setsockopt() can still
// allow the user to specify that a socketaddr can *always* be reused.
                                                                               —?config-win32-common.h"

   在Winsock2中不支持SO_REUSEADDR, 可是我要用的只是端口重用而已?br />
   不过ACE_SOCK_Dgram_Mcast倒是有效Q可惜,不是一个概c?br />
   我后来用很不爽的办法才应付过去,用socket函数先创建好SOCKET句柄后,再用ACE_SOCK_Dgram::set_handle讄。挺郁闷的,不知道有没有好的Ҏ能解x解释?br />

Squirrel 2006-05-15 18:51 发表评论
]]>
[转蝲]用Boost.Python构徏混合pȝ http://www.shnenglu.com/Squirrel/archive/2006/05/15/7193.htmlSquirrelSquirrelMon, 15 May 2006 07:44:00 GMThttp://www.shnenglu.com/Squirrel/archive/2006/05/15/7193.htmlhttp://www.shnenglu.com/Squirrel/comments/7193.htmlhttp://www.shnenglu.com/Squirrel/archive/2006/05/15/7193.html#Feedback2http://www.shnenglu.com/Squirrel/comments/commentRss/7193.htmlhttp://www.shnenglu.com/Squirrel/services/trackbacks/7193.html

目录

摘要

BoostQPython是一个开源的C++E序库,提供cMIDL的接口来把C++cd函数l定到Python。借助于C++强大的编译时内省(introspection)能力和最新的元编E?metaprogramming)技术,它完全用C++来实玎ͼ而不用引入新的语法。Boost.Python丰富的特性和高接口使从底层h混合pȝ的方式设计组件成为可能,从而ɽE序员可以轻村֒q诏的同时用C++高效的编译时多态和Python极其方便的运行时多态?/p>

?/a>

作ؓ两门语言Qpython和C++在很多方面不一栗C++被编译ؓ机器码,python被解?interpreted)执行。Python的动态类?type)pȝl常被认为是灉|性的基础QC++的静态类型是效率的基矟뀂C++有复杂艰q~译时元语言(meta-language)Q而在python里,实际上一切都在运行时发生。然而对很多E序员来_q些不同恰好意味着Python和C++是彼此的完美补。Python E序里的性能瓉部分可以用C++来重写,从而最大化速度。强大的C++E序库的作者选择Python作ؓ中间?middleware)语言Q从而获得灵zȝpȝ集成能力。此外,表面的不同掩盖了二者非常类似的一些地方:

考虑到Python丰富的’C'协作APIQ原则上把C++的类型和函数以类g暴露lC++的接口暴露给Python是可能的。然而,单是Python提供的这U设施对集成C++的支持比较弱。和C++QPython相比Q’C'的抽象机刉常初U,而且完全不支持异常处理。’C'扩展模块的作者必L动管理引用计敎ͼq不但让人恼火的ȝ和单调,q极度容易出错。传l的扩展模块Ҏ产生重复的样板代?boilerplate code)Q从而难于维护,其是要包装的API很复杂时?/p>

上述限制D了一些包装系l的开发。SWIG_ 可能是集成C/C++和Python的包装系l中最行的。一个更q的例子?SIP Q它专门设计来提?Qt 囑Ş用户界面库的Python接口。SWIG和SIP都引入了它们专有的语a来实现语a间绑定。这当然有它的好处,但不得不应付三种不同的语a(PythonQC/C++和接口语a)也带来了实际的和心理上的困难?CXX 软g包展C出它是一个有的包装pȝ。它说明了至一部䆾Python ‘C?API可以通过用户友好得多的C++接口来包装和表现。然而,和SWIG和SIP不一PCXX不支持把C++cd装成新的Pythoncd?/p>

Boost.Python 的特性和目标和很多这Lpȝ有相当程度的重叠。就是说QBoost.Python试图最大化便利性和灉|性,而不引入单独的包装语a。相反,它在q后用静态元~程技术管理很多复杂问题,赋予了用户通过高C++接口来包装C++cd函数的能力,Boost.Python也在如下领域越了早期的pȝQ?/p>

  • C++虚函数支持,虚函数可以用Python来覆?override)
  • 在整个生命周期内对低U指针和引用q行全面理的设?
  • Ҏ扩展(extensions)l织成Python packages的支持,通过中心注册?central registry)来进行语a间类型{?
  • 安全而便利的q接强大的Python序列化引?pickle)的机?
  • C++的lvalue和rvalue的一致的处理规则Q这只能来自对Python和C++两者的cdpȝ的深入理解?

鼓舞Boost.Python开发的关键发现是,传统扩展开发中的大量样板代码都可以通过C++~译时内省来消除。被包装的C++函数的每个参数都必须Ҏ参数cd从Python对象里取出来。类似地Q函数返回值的cd军_了返回值如何从C++转换成Python。参数类型和q回值类型当焉是每个函数的cd的一部分Q正是从q里QBoost.Python推导Z大部分需要的信息?/p>

q种Ҏ导向?用户引导的包?/em> Q尽可能的用UC++的框架直接从要包装的代码里取得信息,q以外的信息qh式提供。大多数引导是自动的Q很需要真正的q涉。因为写接口规范和写被暴露的代码的是同一门全功能语言Q当需要取得控制时用户有了I前强大的能力?/p>

Boost.Python 设计目标

Boost.Python的首要目标是让用户只用C++~译器就能向Python暴露C++cd函数。大体来Ԍ允许用户直接从Python操作C++对象?/p>

然而,有一点很重要Q那是不要 q于 按字面翻译所有接口:必须考虑每种语言的惯用语。例如,虽然C++和Python都有q代器的概念Q表达方式却很不一栗Boost.Python必须能连接这些不同的接口?/p>

必须把Python用户和C++接口的微误用造成的崩溃隔R出于同样原因,应该把C++用户和低UPython ‘C?API隔离Q容易出错的C接口Q比如手动引用计数管理,原始?raw)PyObject指针Q应该用更加健壮?more-robust)替代物来取代?/p>

支持Zlg的开发是臛_重要的,因此被暴露在一个扩展模块里的C++cd应该能够被传递给被暴露在另一个模块中的函敎ͼ而不丢失重要的信息,比如说C++l承关系?/p>

最后,所有的包装必须?非R入的(non-intrusive) Q不能修改甚至看不到原始的C++代码。对只能看见它头文g和二q制文g的第三方Q现有的C++库必L可包装的?/p>

Hello Boost.Python World

现在来预览一下Boost.PythonQƈ看看它如何改qPython的原始包装功能。下面是我们x露的一个函?

char const* greet(unsigned x)
{
   static char const* const msgs[] = { "hello"Q?Boost.Python"Q?world!" };

   if (x > 2)
       throw std::range_error("greet: index out of range");

   return msgs[x];
}

用Python的C API和标准C++来包装这个函敎ͼ我们需要像q样:

extern "C" // 所有Python交互都用C链接和调用习?
{
    // 处理参数/l果转换和检查的包装?
    PyObject* greet_wrap(PyObject* argsQPyObject * keywords)
    {
         int x;
         if (PyArg_ParseTuple(argsQ?i"Q?amp;x))    // 取出/查参?
         {
             char const* result = greet(x);      // 调用被包装的函数
             return PyString_FromString(result); // l果转换成Python
         }
         return 0;                               // 发生了错?
    }

    // 待包装函数表Q函数用q个模块来暴?
    static PyMethodDef methods[] = {
        { "greet"Qgreet_wrapQMETH_VARARGSQ?return one of 3 parts of a greeting" }
        Q{ NULLQNULLQ?QNULL } // sentinel
    };

    // 模块初始化函?
    DL_EXPORT init_hello()
    {
        (void) Py_InitModule("hello"Qmethods); // d成员函数(method)到模?
    }
}

现在看看我们使用Boost.Python来暴露它时的包装代码:

#include <boost/python.hpp>
using namespace boost::python;
BOOST_PYTHON_MODULE(hello)
{
    def("greet"QgreetQ?return one of 3 parts of a greeting");
}

下面是用它的代?

>>> import hello

>>> for x in range(3):
...     print hello.greet(x)
...
hello
Boost.Python
world!

C API版本要冗长的多,此外Q一些它没有正确处理的地方值得提到Q?/p>

  • 原来的函数接受无W号整数QPython ‘C?API仅仅提供了提取有W号整数的方式。如果我们试囑֐hello.greet传递负数Boost.Pyt hon版将抛出Python异常Q而Python ‘C?API版则会l像在C++实现中那栯{换负数到无符h(通常包装成某U很大的?Q然?把不正确的{换结果传l被包装函数?
  • q引起了W二个问题:如果函数的参数大?QC++ greet()被调用时会抛出异常。典型的Q如果C++异常跨越C~译器生成的代码?边界传递,会导致崩溃。正如你在第一个版本中看到的,那儿没有C++脚手?scaffolding)来防止崩溃发生。被Boost.Python包装 q的函数自动包含了异常处理层Q它把未处理的C++异常译成相应的Python异常Q从而保护了Python用户?
  • 一个更微妙的限制是QPython ‘C?API的参数{换机制只能以一U方式取得整数x。如果一个Python long 对象(L_ֺ整数) y可以转换?fit in)unsigned int而不能{换成signed longQPyArg_ParseTuple不能对其q行转换。同样如果被包装的C++ cd含用户定义的隐式operator unsigned int()转换Q它永远不能处理。Boost.Python的动态类型{换注册表允许用户Ld 转换Ҏ?

库概?/a>

q部分简要描qC库的主要Ҏ。ؓ了避免؜淆,忽略了实现细节?/p>

暴露c?Exposing Classes)

C++cdl构以类似的z的接口来暴霌Ӏ假设有:

struct World
{
    void set(std::string msg) { this->msg = msg; }
    std::string greet() { return msg; }
    std::string msg;
};

下面的代码将在我们的扩展模块里暴露它:

#include <boost/python.hpp>

BOOST_PYTHON_MODULE(hello)
{
    class_<World>("World")
        .def("greet"Q?amp;World::greet)
        .def("set"Q?amp;World::set)
    ;
}

管上述代码有某U熟悉的Pythonic的感觉,但语法有时还是有点o惑,因ؓ它看h不像Z习惯的C++代码。但是,q仍然只是标准C++。因为它们灵zȝ语法和操作符重蝲QC++和Python都很适于定义特定领域(?语言( domain-specific (sub)languages) (DSLs)。那是我们在Boost.Python里所做的。把代码拆开来看:

class_<World>("World")

构造类型class_<World>的未命名对象Q把"World"传给它的构造器。这在扩展模块里创Z个叫World的new-style Pythonc,q把它和C++cdWorld在Boost.Python的类型{换注册表里关联v来。我们也可以q么?

class_<World> w("World");

但那样做的话会更J琐Q因为我们不得不再次命名w以调用它的def()成员函数:

w.def("greet"Q?amp;World::greet)

原来的例子里表示成员q入的点的位|没有什么特别的QC++允许L的空白符出现在表意符?token)的Q一边,把点攑֜每行的开始允许用l一的语法把q箋的调用都串v来,不管我们想串多少都行。另一个允许的串接的事实是class_<>成员函数都返回对*this的引用?/p>

因此原来的例子等同于:

class_<World> w("World");
w.def("greet"Q?amp;World::greet);
w.def("set"Q?amp;World::set);

能这h分Boost.Pythoncd装层的组成部分有时候是有用的,但本文的剩下部分一直用简z的语法?/p>

最后来看包装类被用的情况:

>>> import hello
>>> planet = hello.World()
>>> planet.set('howdy')
>>> planet.greet()
'howdy'

构造器(Constructors)

因ؓ我们的Worldcd是一个简单的structQ它有一个隐式的无参?no-argument)(nullary)构造器。Boost.Python默认暴露nullary构造器Q这是我们可以像下面这样写的原?

>>> planet = hello.World()

然而不哪门语aQ设计得好的cd能都需要构造器参数Q以建立他们的不变量(invariants)。在Python里,__init__只是一个特D名U的成员函数(method)Q与q不同,C++里的构造器不能像普通成员函数那样处理。特别是我们不能取它的地址: &World::Worldq样会被报错。库提供了一个不同的接口来指定构造器。假设有:

struct World
{
    World(std::string msg); // d的构造器
    ...

我们可以q样修改包装代码:

class_<World>("World"Qinit<std::string>())
    .def(init<doubleQdouble>())
    ...

当然QC++cd能还有其他的构造器Q我们也可以暴露他们Q只需要向def()传递更多init<?gt;的实?

class <World>("World"Qinit<std::string>())
        .def(init<doubleQdouble>())
        ...

Boost.Python允许被包装的函数Q成员函C及构造器被重载,以映C++重蝲?/p>

数据成员和属?Properties)

C++中的M可公q讉K的数据成员都能轻易的被包装成只读或者只写属?attributes):

class_<World>("World"Qinit<std::string>())
    .def_readonly("msg"Q?amp;World::msg)
    ...

q直接在Python里?

>>> planet = hello.World('howdy')
>>> planet.msg
'howdy'

q不会导致添加属性到World实例__dict__Q从而在包装大型数据l构时节省大量的内存。实际上Q除非从Python昑ּd属性,否则实例__dict__Ҏ不会被创建。Python的这U能力来源于新的Python 2.2 cdpȝQ尤其是descriptor接口和propertycd?/p>

在C++里,可公q讉K的数据成员被认ؓ是糟p设计的表现Q因Z们破坏了装(encapsulation)Q文体向?style guides)通常指示代之?getter" ?"setter"函数。然而在Python里,__getattr__Q__setattr__和从2.2开始有的property意味着属性进入只是程序员控制下的装得更好的语法工具。通过让Python property对用L接可用,Boost.Pythonq接了二者的不同惯用语。如果msg是私有的Q我们仍然能把它暴露为Python里的属?

class_<World>("World"Qinit<std::string>())
    .add_property("msg"Q?amp;World::greetQ?amp;World::set)
    ...

上面的例子映了Z熟悉的Python 2.2+里的property用法:

>>> class World(object):
...     __init__(selfQmsg):
...         self.__msg = msg
...     def greet(self):
...         return self.__msg
...     def set(selfQmsg):
...         self.__msg = msg
...     msg = property(greetQset)

操作W重?/a>

能给用户定义cd定义术操作W一直是两门语言的数D取得成功一个重要因素。像 Numpy q样的Y件包的成功证明了在扩展模块中暴露操作W能产生巨大能量。Boost.Pythonl包装操作符重蝲提供了简z的机制。下面是包装Boost的有理数? rational number library)的代码的片断:

class_<rational<int> >("rational_int")
  .def(init<intQint>()) // constructorQe.g. rational_int(3Q?)
  .def("numerator"Q?amp;rational<int>::numerator)
  .def("denominator"Q?amp;rational<int>::denominator)
  .def(-self)        // __neg__ (unary minus)
  .def(self + self)  // __add__ (homogeneous)
  .def(self * self)  // __mul__
  .def(self + int()) // __add__ (heterogenous)
  .def(int() + self) // __radd__

q种法是通过单的应用"表达式模?("expression templates") [VELD1995] 来施加的Q?表达式模?是一U最初ؓ优化高性能矩阵代数表达式而开发的技术。本质是不立卌行计,而重载操作符来构造描q计的cd。在矩阵代数里,当考虑整个表达式的l构Q而不?贪婪?Ҏ步操作求值时Q经常可以获得戏剧性的优化。Boost.Python用同L技术来构徏Z包含 self 的表辑ּ的适当的Python 成员函数对象(method object)?/p>

l承

要在Boost.Python里描qC++l承关系Q可以像下面q样把可选的bases<?gt;参数d到class_<?gt;模板参数表里:

class_<DerivedQbases<Base1QBase2> >("Derived")
     ...

q样有两个效果:

  1. 当class_<?gt;被创建时Q在Boost.Python的注册表里查扑֯应于Base1和Base2的Pythoncd对象Q然后作为新的Python衍生c?型对象的基类。因而暴露给Base1和Base2的成员函数自动成Z衍生cd的成员。因为注册表是全局的,即暴露衍生cd的模 块和它的M基类的模块不同,l承同样有效?
  2. 衍生cd基类的C++转换被添加到Boost.Python注册表。因此期待Q一基类对象(的指针或引用)的被包装C++成员函数可以被包?了Q一基类的衍生实例的对象调用。类T的被包装成员函数被视为具有隐式的W一个参数T&Q那么ؓ了让衍生对象能调用基cL 员函敎ͼq些转换是必需的?

当然从被包装的C++cd例衍生新的PythoncL可能的。这是因为Boost.Python使用了new-style classpȝQ这套系l在Python内置cd上工作良好。但有一个重要细节不同: Python内置cd一般在__new__函数里徏立不变量(invariants)Q从而衍生类不用在调用它的成员函数前调用基类的__init__:

>>> class L(list):
...      def __init__(self):
...          pass
...
>>> L().reverse()
>>>

因ؓC++对象构造是一步操?one-step operation)Q直到参数可用C++实例数据才能被构造,在__init__函数?

>>> class D(SomeBoostPythonClass):
...      def __init__(self):
...          pass
...
>>> D().some_boost_python_method()
Traceback (most recent call last):
  File "<stdin>"Qline 1Qin ?
TypeError: bad argument type for built-in operation

发生错误的原因是Boost.Python 在实例D里找不到cdSomeBoostPythonClass的实例数据;D的__init__函数遮盖了基cȝ构造函数。可以通过删除D的__init__函数或是让它昑ּ的调用SomeBoostPythonClass.__init__(?来纠正错误?/p>

虚函?/a>

在Python里从扩展c衍生新的类型没太大意思,除非它们在C++里能被多态的使用。换句话_当在C++里通过基类指针/引用调用Python成员函数ӞPython成员函数的实现应该看h像是覆盖(override)了C++虚函数的实现。因改变虚函数的行ؓ的唯一Ҏ是在衍生c里覆盖(override)它,用户必须构造一个特D的衍生cL分派(dispatch)多态类的虚函数?

//
// 要包装的接口:
//
class Base
{
 public:
    virtual int f(std::string x) { return 42; }
    virtual ~Base();
};

int calls_f(Base const& bQstd::string x) { return b.f(x); }

//
// 包装代码
//

// 分派者类(Dispatcher class)
struct BaseWrap : Base
{
    // 储存指向Python对象的指?
    BaseWrap(PyObject* self_) : self(self_) {}
    PyObject* self;

    // 当f没有被覆?override)时的~省实现
    int f_default(std::string x) { return this->Base::f(x); }
    // 分派实现
    int f(std::string x) { return call_method<int>(selfQ?f"Qx); }
};

...
    def("calls_f"Qcalls_f);
    class_<BaseQBaseWrap>("Base")
        .def("f"Q?amp;Base::fQ?amp;BaseWrap::f_default)
        ;

下面是一些python演示代码:

>>> class Derived(Base):
...     def f(selfQs):
...          return len(s)
...
>>> calls_f(Base()Q?foo')
42
>>> calls_f(Derived()Q?forty-two')
9

对分z者类(Dispatcher class)Q要注意:

更深层次的反即出?Deeper Reflection on the Horizon)?

无可否认Q重复这U公式化的流E是冗长乏味的。尤其是目里有大量多态类的时候。这反映了C++~译时内省能力的必然限制:无法枚Dcȝ成员来判断哪个是虚函数。不q,一个很有希望的目已经启动Q致力于写一个前端程序来从C++头文件自动生成这些分z者类(以及其它包装代码)?/p>

Pyste 是由Bruno da Silva de Oliveira开发的Q基?GCC_XML 构徏。GCC_XML可以生成XML版本的GCC内部E序描述。GCC是一U高度符?译注QC++标准)的编译器Q从而确保了Ҏ复杂的模板代码的正确处理和对底层cdpȝ的完全访问。和Boost.Python的哲学一_Pyste接口描述既不侵入被包装的代码Q也不用某种不熟悉的语言来表达,相反Q它?00%的纯Python脚本。如果Pyste成功的话Q将标志着我们的很多用户不用再什么都直接用C++包装。它允许我们选择把一些元E序(metaprogram)代码从C++Ud到Python。我们期待不久后不仅用户QBoost.Python开发者自׃能以混合的思\来考虑("thinking hybrid")他们自己的代码?/p>

序列?Serialization)

序列化是把内存中的对象{换成可以保存到磁盘上或通过|络传送的格式的过E。序列化后的对象(最常见的是单字W串)可以被重新取得ƈ转换回原来的对象。好的序列化pȝ能够自动转换整个对象层次(object hierarchies)。Python的标准pickle模块正是q样的系l。它利用语言强大的运行时内省来序列化几乎是Q意的用户定义对象。加上一些简单的非R入限定,q种强大的设施可以被扩展成对被包装的C++对象也有效。下面是一个例?

#include <string>

struct World
{
    World(std::string a_msg) : msg(a_msg) {}
    std::string greet() const { return msg; }
    std::string msg;
};

#include <boost/python.hpp>
using namespace boost::python;

struct World_picklers : pickle_suite
{
  static tuple
  getinitargs(World const& w) { return make_tuple(w.greet()); }
};

BOOST_PYTHON_MODULE(hello)
{
    class_<World>("World"Qinit<std::string>())
        .def("greet"Q?amp;World::greet)
        .def_pickle(World_picklers())
    ;
}

现在让我们创Z个World对象q把它放到磁盘上:

>>> import hello
>>> import pickle
>>> a_world = hello.World("howdy")
>>> pickle.dump(a_worldQopen("my_world"Q?w"))

在可能不同的计算机的可能不同的操作系l的可能不同的脚本中:

>>> import pickle
>>> resurrected_world = pickle.load(open("my_world"Q?r"))
>>> resurrected_world.greet()
'howdy'

当然也可以用cPickle来获得更快的处理速度?/p>

Boost.Python的pickle_suite完全支持标准Python文定义的pickle协议。类似Python里的__getinitargs__函数Qpickle_suite的getinitargs()负责创徏参数tuple来重pickle了的对象。Python pickle协议中的其他元素Q__getstate__ 和__setstate__可以通过C++ getstate和setstate函数来可选的提供。C++的静态类型系l允许库在编译时保没有意义的函数组?例如Q没有setstate getstate)不会被用?/p>

要想序列化更复杂的C++对象需要做比上面的例子E微多点的工作。幸q的是Object接口(参见下一?在保持代码便于管理上帮了大忙?/p>

对象接口(Object interface)

无所不在的PyObject*Q手动引用计敎ͼ需要记住是哪个API调用q回?新的"(自n拥有?引用或是"借来?(原始?引用Q这些可能有l验的C语言扩展模块的作者都熟悉。这些约束不仅麻烦,更是错误的主要来源,其是存在异常的时候?/p>

Boost.Python提供了一个objectc,它自动化了引用计数ƈ提供Lcd的C++对象到Python的{换。这极大的减M未来的扩展模块作者的学习负担?/p>

从Q一cd创徏object极度?

object s("helloQworld");   // s 理一个Python字符?

object可以和所有其它类型进行模板化的交互,自动的进行到Python的{换。这一切自然得很容易被忽略不计:

object ten_Os = 10 * s[4]; // -> "oooooooooo"

上面的例子中Q在索引和乘法操作被调用前,4?0被{换成了Python对象?/p>

extract<T>cL板可以用来把Python对对象{换成C++cd:

double x = extract<double>(o);

如果M方向的{换不能执行,在q行时抛Z个适当的异常?/p>

伴随objectcd的是一套衍生类型,可能的映射Python的内|类?listQdictQtuple{?。这样就能方便的从C++操作q些高cd?

dict d;
d["some"] = "thing";
d["lucky_number"] = 13;
list l = d.keys();

q看h和工作v来几乎就像是通常的python代码Q但它实际上是纯的C++。当然我们能包装接受或返回object实例的函数?/p>

从؜合的思\思?Thinking hybrid)

因ؓl合~程语言h实际的和心理的困难,在进行Q何实际开发前军_使用单一的语a是普遍现象。对很多应用来说Q性能上的考虑军_了核心算法要用编译语a实现。不q的是,因ؓ静态类型系l的复杂性,我们行时性能要付出开发时间大量增长的代h。经验表明,和开发相应的Python代码比v来,开发可l护的C++代码通常需要更长的旉和艰隑־多才能获得的工作l验。即使开发者觉得只用一门编译语a开发挺好,Z用户Q他们也l常用某U类型的特别的脚本层来补充系l,哪怕他们永q不会得到同L好处?/p>

Boost.Python让我们能 think hybrid 。Python可以用来快速搭建新的应用的原型Q在开发能工作的系l时Q它的易用性和大量的标准库使我们处于领先。需要的话,可以用能工作的代码来扑և限制速度的热?rate-limiting hotspots)。ؓ了最大化性能Q这些热点可以用C++来重新实玎ͼ然后用Boost.Pythonl定来连q已有的高q程(译注Q指PythonE序)?/p>

当然Q如果一开始就清楚很多法最后不得不用C++来实玎ͼq种 由顶至下(top-down) 的方法就没那么吸引h了。幸q的是,Boost.Python也允许我们?由底至上(bottom-up) 的方法。我们非常成功的把这U方法用在了一个用于科学应用的工具pY件的开发上。这个工L开始主要是一个带Boost.Pythonl定的C++cdQ接下来有一段旉增长主要集中在C++部分Q随着工具变得越来越完整Q越来越多新d的功能可以用Python来实现?/p>

http://static.flickr.com/55/124987534_34375196e6.jpg?v=0

上图是实现新的算法时新添加的C++代码和Python代码的估计比率随旉变化的情c我们预计这个比率会辑ֈ接近70% (Python)。能够主要用Python而不是更困难的静态类型语a来解x问题Q这是我们在Boost.Python上的投入的回报。我们的所有代码都能从Python讉KQ这使得更广泛的开发者可以用它来快速开发新的应用?/p>

开发历?/a>

Boost.Python的第一版是由Dave Abrahams在Dragon Systems开发的。在那里他非常荣q的请到Tim Peters作ؓ他的"Python之禅"( "The Zen of Python")导师。Dave的工作之一是开发基于Python的自然语a处理pȝ。因为最l要被用于嵌入式gQ系l计密集的内核L被假设成要用C++来重写以优化速度和内存需求量(memory footprint) [1] 。这个项目也想用Python试脚本 [2] 来测试所有的C++代码。当时我们知道的l定C++和Python的唯一工具?SWIG Q但那时它处理C++的能力比较弱。要说在那时对Boost.Python所使用Ҏ的可能优之处有了什么深L见,那是骗h的。Dave对花俏的C++模板技巧的兴趣和娴熟刚好到了能真正做点什么的时候,Boost.Python那样出CQ因为它满了需求,因ؓ它看h挺酷Q值得一试?/p>

早期的版本针对的许多基本目标和在q篇论文中描q的相同。最显著的区别在于早期版本的语法要稍微麻烦一点,~ZҎ作符重蝲QpicklingQ基于组件的开发的专门支持。后面三个特性很快就被Ullrich Koethe和Ralf Grosse-Kunstleve [3] 加上了。其他热心的贡献?contributors)也出来A献了一些改q,如对嵌套模块和成员函数的支持{?/p>

?001q早期时开发已l稳定下来了Q很有新的Ҏ添加,然而这时一个烦人的问题暴露出来了:Ralf已经开始在一个?EDG 前端的编译器的预发布版上试Boost.PythonQ这时Boost.Python内核中负责处理Python和C++的类型{换的机制(mechanism)~译p|了。结果证明我们一直在利用一个bugQ这个bug在所有我们测试过的C++~译器实C都非常普遍。我们知道随着C++~译器很快变得更加标准兼容,库将开始在更多的^Cp|。很不幸Q因套机制是库的功能的中枢,解决问题看v来非常困难?/p>

q运的是那一q的后期QLawrence Berkeley和后来的Lawrence Livermore National labs?Boost Consulting {订了支持Boost.Python的开发的合同。这样就有了新的Z来处理库的基本问题,从而确保将来的发展。重新设计开始于低cd转换架构Q内|的标准兼容和对Zlg的开发的支持(和不得不昑ּ的跨模块边界导入或导出转换的第一版Ş成对?。对Python和C++对象的关p进行了分析Q从而能更直观的处理C++ lvalues和rvalues?/p>

Python 2.2里出现的强大的新cdpȝ使得选择是否l护对Python 1.5.2的兼Ҏ变得容易了Q这个丢弃大量精心制作的仅仅用来模拟classic Pythoncȝ代码的机会,好的令h无法拒绝。另外,Python iterators ?descriptors提供了重要且优雅的工h描述cM的C++l构。一般化了的对象接口的开发允许我们进一步把C++E序员和使用Python C API带来的危险性和语法负担隔离开。大量的其他Ҏ在q个阶段被加了进来,包括C++异常译Q改q的重蝲函数支持Q还有最重要的用来处理指针和引用的CallPolicies?/p>

?002q十月,W二版的Boost.Python发布了。那以后的开发集中在改进对C++q行时多态和指针的支持上。特别是Peter Dimov的y妙的boost::shared_ptr设计使我们能l؜和系l开发者提供一致的接口Q用于跨语a藩篱来回Ud对象而不丢失信息?/p>

刚开始,我们担心Boost.Python v2的复杂性会ȝ贡献者,?Pyste 和几个其他重要特性的贡献(contribution)的出Cɘq些担心昑־多余了。每天出现在Python C++-sig上的问题和希望得到的改进的积?backlog)表明了库正在被用。对我们来说Q未来看h很光明?/p>

l论

Boost.Python 实现了两U功能丰富的优秀的语a环境间的无缝协作。因为它利用模板元编E技术来对类型和函数q行内省Q用hq用不着再学W三U语a:接口定义是用z而可l护的C++写的。同P包装pȝ不用再解析C++头文件或是描q类型系l:~译器都l我们做了?/p>

计算密集的Q务适合强大的C++Q它一般不可能用纯Python来实现。然而像序列化这L工作Q可能用Python很简单,用C++非常困难。假如有从底层开始构建؜合系l的奢侈Q我们有新的信心和动力来q行设计?/p>



Squirrel 2006-05-15 15:44 发表评论
]]>
Pythonwin VS Eclipse PyDevhttp://www.shnenglu.com/Squirrel/archive/2006/05/15/7187.htmlSquirrelSquirrelMon, 15 May 2006 07:17:00 GMThttp://www.shnenglu.com/Squirrel/archive/2006/05/15/7187.htmlhttp://www.shnenglu.com/Squirrel/comments/7187.htmlhttp://www.shnenglu.com/Squirrel/archive/2006/05/15/7187.html#Feedback2http://www.shnenglu.com/Squirrel/comments/commentRss/7187.htmlhttp://www.shnenglu.com/Squirrel/services/trackbacks/7187.html   同样作ؓIDEQPythonwin ?IDLE 有不o人兴奋的地方Q我开始用Pythonwin也正是由于它的DEBUG环境和别人的推荐。可当我调试Ӟ比如Q一个程序按两次F5Q就出现“Pythonwin.exe 遇到问题需要关闭”,接着是Runtime Error和内存不能ؓ诅R然后必重启Pythonwin才能用!遇到q样的问题,恐怕大多用L心理都难以承受?br />   我后来想起了Eclipse+CDTQ那么有Eclipse+PDT么?果然Q看到网上有Eclipse+PyDev?br />   在Eclipse中选择菜单Q?/font>Help—Software Updates—Find And Install Q选择 Search for new features to intallQ点 New Remote Site 按钮Q输?http://pydev.sf.net/updatesQ?/font>下蝲q安装?br />   配置旉要制定Python解释器,选择正确的\径即可?br />   然后可以在Eclipse下开发调试PythonE序了?br />pyDev.JPG
   
   我也下过BOAQ但感觉现在它还有不缺P毕竟才是alpha版。估计等?.0出来很了?br />   WingIDE 不知道怎么P下次试吧?/font>


Squirrel 2006-05-15 15:17 发表评论
]]>
May it behttp://www.shnenglu.com/Squirrel/archive/2005/11/28/1351.htmlSquirrelSquirrelMon, 28 Nov 2005 00:46:00 GMThttp://www.shnenglu.com/Squirrel/archive/2005/11/28/1351.htmlhttp://www.shnenglu.com/Squirrel/comments/1351.htmlhttp://www.shnenglu.com/Squirrel/archive/2005/11/28/1351.html#Feedback0http://www.shnenglu.com/Squirrel/comments/commentRss/1351.htmlhttp://www.shnenglu.com/Squirrel/services/trackbacks/1351.htmlShines down upon you
May it be when darkness falls
Your heart will be true
You walk a lonely road
Oh! How far you are from home

Morni? utt̔li? (Quenya: Darkness has come)
Believe and you will find your way
Morni? alanti? (Quenya: Darkness has fallen)
A promise lives within you now

May it be the shadow's call
Will fly away
May it be your journey on
To light the day
When the night is overcome
You may rise to find the sun

Morni? utt̔li? (Quenya: Darkness has come)
Believe and you will find your way

Morni? alanti? (Quenya: Darkness has fallen)
A promise lives within you now

A promise lives within you now

Squirrel 2005-11-28 08:46 发表评论
]]>
þþþùƷ| 99ƷѾþþþþ | þþþavۺϲҰ| 999þþƷ| ƷۺϾþþþþ97| ¶ۺϼ¾þ| ޹СƵƷþþ| þþƷһ| þŷ޹ۺ| ھƷþù| Ļձ޾þþ| ˾þۺӰԺ| ۺϾƷ㽶þ| ޹Ʒþþϼ2 | ŷ鶹þþþþ| þ99Ʒþþþþ| þþƷѹƬС| ݺɫۺϾþȥ| ɫþùƷ12p| ޾ƷƵþþ| þùֱ| ˾þþƷӰԺ| ձŷƷһҳþ| þ˾Ʒһ | þþƷĻ鶹| 91ƷۺϾþþþþ| aaþ| ˳þõӰվ| þþһ | þþþùƷ鶹ARӰԺ| þ޾Ʒվ| þþƷƵ| Ʒþþһ| һþ㽶߿ۿ | Ʒþþþþ99| ޺ݺۺϾþѿ| ˾þþƷ鶹һ| ɫۺϾþ | þõӰ2021| רþ| þþƵ|