摘要: 一 概述: HttpWatch強大的網(wǎng)頁數(shù)據(jù)分析工具.集成在Internet Explorer工具欄.包括網(wǎng)頁摘要.Cookies管理.緩存管理.消息頭發(fā)送/接受.字符查詢.POST 數(shù)據(jù)和目錄管理功能.報告輸出 HttpWatch 是一款能夠收集并顯示頁頁深層信息的軟件。它不用代理服務(wù)器或一些復(fù)雜的網(wǎng)絡(luò)監(jiān)控工具,就能夠在顯示網(wǎng)頁同時顯示網(wǎng)頁請求和回應(yīng)的日志信息。甚至可以顯示瀏覽器緩存和IE之間...  閱讀全文
          posted @ 2008-12-26 10:31 小馬歌 閱讀(802) | 評論 (0)編輯 收藏
           

          匹配中文字符的正則表達式: [\u4e00-\u9fa5]

          匹配雙字節(jié)字符(包括漢字在內(nèi)):[^\x00-\xff]

          應(yīng)用:計算字符串的長度(一個雙字節(jié)字符長度計2,ASCII字符計1)

          String.prototype.len=function(){return this.replace([^\x00-\xff]/g,"aa").length;}

          匹配空行的正則表達式:\n[\s| ]*\r

          匹配HTML標(biāo)記的正則表達式:/<(.*)>.*<\/\1>|<(.*) \/>/

          匹配首尾空格的正則表達式:(^\s*)|(\s*$)

          應(yīng)用:javascript中沒有像vbscript那樣的trim函數(shù),我們就可以利用這個表達式來實現(xiàn),如下:

          String.prototype.trim = function()
          {
          return this.replace(/(^\s*)|(\s*$)/g, "");
          }

          利用正則表達式分解和轉(zhuǎn)換IP地址:

          下面是利用正則表達式匹配IP地址,并將IP地址轉(zhuǎn)換成對應(yīng)數(shù)值的Javascript程序:

          function IP2V(ip)
          {
          re=/(\d+)\.(\d+)\.(\d+)\.(\d+)/g //匹配IP地址的正則表達式
          if(re.test(ip))
          {
          return RegExp.$1*Math.pow(255,3))+RegExp.$2*Math.pow(255,2))+RegExp.$3*255+RegExp.$4*1
          }
          else
          {
          throw new Error("Not a valid IP address!")
          }
          }

          不過上面的程序如果不用正則表達式,而直接用split函數(shù)來分解可能更簡單,程序如下:

          var ip="10.100.20.168"
          ip=ip.split(".")
          alert("IP值是:"+(ip[0]*255*255*255+ip[1]*255*255+ip[2]*255+ip[3]*1))

          匹配Email地址的正則表達式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*

          匹配網(wǎng)址URL的正則表達式:http://([/w-]+/.)+[/w-]+(/[/w- ./?%&=]*)?

          利用正則表達式去除字串中重復(fù)的字符的算法程序:[注:此程序不正確,原因見本貼回復(fù)]

          var s="abacabefgeeii"
          var s1=s.replace(/(.).*\1/g,"$1")
          var re=new RegExp("["+s1+"]","g")
          var s2=s.replace(re,"")
          alert(s1+s2) //結(jié)果為:abcefgi

          這個方法對于字符順序有要求的字符串可能不適用。

          得用正則表達式從URL地址中提取文件名的javascript程序,如下結(jié)果為page1

          s=" s=s.replace(/(.*\/){0,}([^\.]+).*/ig,"$2")
          alert(s)

          利用正則表達式限制網(wǎng)頁表單里的文本框輸入內(nèi)容:

          用正則表達式限制只能輸入中文:onkeyup="value=value.replace(/[^\u4E00-\u9FA5]/g,´´)" onbeforepaste="clipboardData.setData(´text´,clipboardData.getData(´text´).replace(/[^\u4E00-\u9FA5]/g,´´))"

          用正則表達式限制只能輸入全角字符: onkeyup="value=value.replace(/[^\uFF00-\uFFFF]/g,´´)" onbeforepaste="clipboardData.setData(´text´,clipboardData.getData(´text´).replace(/[^\uFF00-\uFFFF]/g,´´))"

          用正則表達式限制只能輸入數(shù)字:onkeyup="value=value.replace(/[^\d]/g,´´) "onbeforepaste="clipboardData.setData(´text´,clipboardData.getData(´text´).replace(/[^\d]/g,´´))"

          用正則表達式限制只能輸入數(shù)字和英文:onkeyup="value=value.replace(/[\W]/g,´´) "onbeforepaste="clipboardData.setData(´text´,clipboardData.getData(´text´).replace(/[^\d]/g,´´))"

          文章出處:http://www.diybl.com/course/3_program/java/javajs/2008513/115720.html

          posted @ 2008-12-26 10:26 小馬歌 閱讀(1693) | 評論 (0)編輯 收藏
           
          轉(zhuǎn)自:http://www.zengrong.net/?p=393

          Flash Player 9.0.115發(fā)布了,這是一個支持H.264的正式版本。關(guān)于H.264,已經(jīng)說得太多,播放H.264的視頻也很簡單,用NetStream即可(也就是播放FLV的那一套,想了解的可以看這篇官方提供的教程),但是怎么把現(xiàn)有的視頻壓縮成Flash Player支持的H.264格式呢?

          首先,要了解Flash Player 9.0.115對視頻編碼到底支持到哪個程度。

          下面是Adobe官方提供的一個Flash Player支持的視頻編碼列表(原文):

          視頻編碼 SWF 文件格式版本(發(fā)布的版本) 支持播放的最小Flash Player版本
          Sorenson Spark 6 6
          On2 VP6 6 8
          H.264 (MPEG-4 Part 10) 9 9.0.115.0*
          音頻編碼 SWF 文件格式版本(發(fā)布的版本) 支持播放的最小Flash Player版本
          ADPCM 6 6
          MP3 6 6
          HE-AAC (MPEG-4 Part 3) 9 9.0.115.0*

          *Flash Player 可以播放視頻編碼為H.264,音頻編碼為AAC的標(biāo)準(zhǔn)MPEG-4文件。文件的擴展名可以是:F4V, MP4, M4A, MOV, MP4V, 3GP, 3G2等等。

          注意:如果沒有特別說明,下面的Flash Player都指Flash Player 9(v 9.0.115.0)

          Flash Player 9 (v 9.0.115.0) 支持下面的 MPEG-4 標(biāo)準(zhǔn)的子集:

          MPEG-4 標(biāo)準(zhǔn) Flash Player Update 3
          ISO/IEC 14496-3 (Audio AAC) AAC Main; AAC LC; SBR
          ISO/IEC 14496-10 (Video AVC) Base (BP); Main (MP); High (HiP). All levels are supported.
          ISO/IEC 14496-12 (Container) 1 Audio track; 1 Video track
          3GPP TS 26.245 (Timed text format) Full support.

          那么,什么是H.264?“MPEG4 Part 10”是什么?它和“Part 3”、“Part 2” 有什么關(guān)系?可以看這篇文章

          簡單的講,H.264、MPEG4 Part 10、MPEG4 AVC和ISO/IEC 14496-10 都是一個東東,就是一種視頻編碼格式,同時也是高清電影采用的視頻編碼格式之一(另外兩種是MPEG2和VC-1)。

          而平常我們熟悉的DivX以及XviD編碼,都屬于MPEG4標(biāo)準(zhǔn)的范疇,但它們屬于MPEG4 Part 2,F(xiàn)lash Player是不支持它們的。

          了解了基礎(chǔ)知識之后,我們首先需要找到一個編碼工具。

          選擇一個優(yōu)秀的壓縮工具至關(guān)重要。Flash CS3自帶的用于壓縮FLV的壓縮器自然是無法勝任了。可是網(wǎng)上的視頻轉(zhuǎn)換工具多如牛毛,要找一款好用的真的很難。本著“免費、易用、專業(yè)、通吃”這四個標(biāo)準(zhǔn),經(jīng)過大量測試,終于找到一款優(yōu)秀的國產(chǎn)編碼軟件MediaCoder(中文名:影音轉(zhuǎn)碼寶盒),以下是來自MediaCoder官方網(wǎng)站的介紹:

          MediaCoder是一個免費的通用音頻/視頻批量轉(zhuǎn)碼工具,它將眾多來自開源社區(qū)的優(yōu)秀音頻視頻編解碼器和工具整合為一個通用的解決方案,可以將音頻、視頻文件在各種格式之間進行轉(zhuǎn)換。

          功能和特點

          • 基于優(yōu)秀的眾多的開源編解碼后臺,能夠解碼和編碼的格式多
          • 極為豐富的可調(diào)整的編碼參數(shù)
          • 全部編解碼器自帶,不依賴于系統(tǒng)的編解碼器和任何組件
          • 良好的可擴展的程序架構(gòu),快速適應(yīng)新的需求,不斷增加新的格式的支持
          • 利用腳本語言擴展的界面,有支持眾多影音設(shè)備(如PSPiPod)的專用界面
          • 高性能,特別在雙核處理器上表現(xiàn)優(yōu)異


          典型應(yīng)用

          • 提高影音文件壓縮率,減小其文件尺寸
          • 轉(zhuǎn)換至可在各種影音設(shè)備上播放的影音文件,如MP3播放器、MP4播放器、手機、PDA、VCD/DVD播放機
          • 提取視頻文件中的音軌并轉(zhuǎn)換成MP3、AAC、WMA等音頻文件
          • 修復(fù)和改善一些損壞的、部分下載的或質(zhì)量不佳的影音文件

          支持格式

          *僅支持輸入

          編碼工具搞定,接著就可以“制作”影片了。

          我采用的源片是著名的Backkom Assa Game Contest片段,片源編碼如下:

          G:\Movie\Backkom\Assa Game Contest.wmv
          General
          Complete name : G:\Movie\Backkom\Assa Game Contest.wmv
          Format : Windows Media
          File size : 1.89 MiB
          PlayTime : 33s 991ms
          Bit rate : 467 Kbps
          Movie name : Assa
          Performer : Aaron Lim
          Copyright : rg animation studios
          Comment : rg animation studios
          Video
          Codec : WMV3
          Codec/Info : Windows Media Video 9
          Bit rate : 408 Kbps
          Width : 320 pixels
          Height : 240 pixels
          Aspect ratio : 4/3
          Audio
          Codec : WMA2
          Codec/Info : Windows Media Audio 2
          Bit rate : 48 Kbps
          Channel(s) : 2 channels
          Sampling rate : 44 KHz

          在壓縮前,最重要的就是在MediaCoder中選擇視頻編碼和音頻編碼。根據(jù)上面的表格我們知道,F(xiàn)lash Player 9.0.115支持H.264視頻編碼和HE-AAC音頻編碼。下圖是我在MediaCoder中的設(shè)置。

          H.264視頻設(shè)置
          H.264視頻設(shè)置

           

          HE-AAC音頻編碼
          HE-AAC音頻設(shè)置

           

          h264video2
          視頻大小設(shè)置

          將這三個設(shè)置調(diào)整好即可。H.264的編碼優(yōu)于WMV9,所以在壓縮的時候,選擇的視頻和音頻碼率都小于源文件的碼率。

          轉(zhuǎn)換完后的視頻擴展名為MP4,詳細(xì)編碼信息如下:

          G:\Movie\Backkom\Assa Game Contest.mp4
          General
          Complete name : G:\Movie\Backkom\Assa Game Contest.mp4
          Format : MPEG-4
          Format/Info : ISO 14496-1 Base Media
          Format/Family : MPEG-4
          File size : 1.40 MiB
          PlayTime : 33s 920ms
          Bit rate : 347 Kbps
          StreamSize : 11.2 KiB
          Encoded date : UTC 2007-12-06 15:51:38
          Tagged date : UTC 2007-12-06 15:51:38
          Video #1
          Codec : H.264
          Codec/Info : H.264 (3GPP)
          PlayTime : 33s 920ms
          Bit rate : 314 Kbps
          Width : 320 pixels
          Height : 240 pixels
          Aspect ratio : 4/3
          Frame rate : 25.000 fps
          Bits/(Pixel*Frame) : 0.160
          StreamSize : 1.27 MiB
          Encoded date : UTC 2007-12-06 15:51:38
          Tagged date : UTC 2007-12-06 15:51:38
          Audio #2
          Codec : AAC LC-SBR
          Codec/Info : AAC Low Complexity with Spectral Band Replication
          PlayTime : 32s 415ms
          Bit rate : 32 Kbps
          Bit rate mode : VBR
          Channel(s) : 2 channels
          Sampling rate : 44 KHz
          Resolution : 16 bits
          StreamSize : 126 KiB
          Encoded date : UTC 2007-12-06 15:51:38
          Tagged date : UTC 2007-12-06 15:51:38

          此視頻在Flash Player 9.0.115中順利播放,聲音也沒有問題。

          研究一下視頻和音頻的組合

          到了這里,就有一些問題了。H.264視頻是否一定要搭配AAC音頻呢?搭配MP3行么?我壓縮了一個采用H.264視頻編碼,Mp3音頻編碼(采用LAME MP3)的影片,用終極解碼播放正常,但是在Flash Player中,只有圖像可以顯示,卻聽不到聲音。下面是這個文件的編碼信息:

          F:\Material\Flash Platform\Flash\Cases\播放H.264視頻\333.mp4
          General
          Complete name : F:\Material\Flash Platform\Flash\Cases\播放H.264視頻\333.mp4
          Format : MPEG-4
          Format/Info : ISO 14496-1 Base Media
          Format/Family : MPEG-4
          File size : 2.59 MiB
          PlayTime : 33s 920ms
          Bit rate : 641 Kbps
          StreamSize : 13.9 KiB
          Encoded date : UTC 2007-12-05 09:21:21
          Tagged date : UTC 2007-12-05 09:21:21
          Video #1
          Codec : H.264
          Codec/Info : H.264 (3GPP)
          PlayTime : 33s 920ms
          Bit rate : 516 Kbps
          Width : 320 pixels
          Height : 240 pixels
          Aspect ratio : 4/3
          Frame rate : 25.000 fps
          Bits/(Pixel*Frame) : 0.260
          StreamSize : 2.09 MiB
          Encoded date : UTC 2007-12-05 09:21:21
          Tagged date : UTC 2007-12-05 09:21:21
          Audio #2
          Codec : MPEG-1 Audio
          PlayTime : 32s 365ms
          Bit rate : 128 Kbps
          Bit rate mode : CBR
          Channel(s) : 2 channels
          Sampling rate : 44 KHz
          Resolution : 16 bits
          StreamSize : 506 KiB
          Encoded date : UTC 2007-12-05 09:21:21
          Tagged date : UTC 2007-12-05 09:21:21

          又測試了H.264+MP3用AVI封裝和3GP封裝,在Flash Player中都無法播放聲音。看來只有H.264+AAC可以被Flash Player支持。封裝可以使用3GP或者MP4,但不支持MKV封裝。

          關(guān)于封裝容器和視頻文件后綴

          我們知道,我們不能僅僅從視頻文件的擴展名判斷文件的編碼。因為很多擴展名是支持多種編碼的。例如AVI就只是一種封裝容器,它里面的視頻和音頻編碼可以有很多種組合。可以是DivX,也可以是XviD,還可以是MPEG-1。下面的表格(表格來源,ZRong做部分調(diào)整)簡單的描述了幾種封裝容器和視頻、音頻編碼的對應(yīng)情況:

          封裝容器 視頻流編碼格式 音頻流編碼格式 Flash Player是否支持
          AVI Xvid MP3 不支持
          AVI Divx MP3 不支持
          MKV Xvid MP3 不支持
          MKV Xvid AAC 不支持
          MKV H.264 AAC 不支持
          MP4 H.264 AAC 支持
          3GP H.263 AAC 不支持
          3GP H.264 AAC 支持
          FLV Sorenson Spark MP3 支持
          FLV On2 VP6 MP3 支持

          從上表可以看出,要讓Flash Player成功播放H.264視頻,最好采用3GP或者MP4封裝容器。

          AAC編碼的混亂情況

          上面的壓縮,AAC編碼器使用的都是Nero Encoder,其中“規(guī)格”有這樣幾個選項:Auto、LC-AAC、LE-AAC和HE-AAC v2。經(jīng)過測試,這幾個規(guī)格壓縮的音頻都可以被Flash Player支持。

          Nero Encoder的規(guī)格|
          Nero Encoder的選項

          如果采用CT AAC+編碼器,選項就變成了下面這樣,更加復(fù)雜了。經(jīng)過測試,這幾個選項的組合也都可以被Flash Player支持。不論選擇MPEG-4 AAC還是MPEG-2 AAC,都沒有問題。

          h264ctaac
          CT AAC+的選項

          如果采用FAAC編碼器,選項就變成了下面這樣。經(jīng)過測試,這幾個選項的組合也都可以被Flash Player支持,MPEG版本的選擇也沒有關(guān)系。

          h264faac
          FAAC的選項

          事實上,NERO Encoder和CT AAC+中的LC-AAC,就是FAAC中的Low Complexity(無長時預(yù)測的AAC);而NERO Encoder中的HE-AAC,就是CT AAC+中的aacPlus,它加了SBR(spectral band replication),HE代表high efficiency。這也是為什么前面壓縮WMV視頻的時候,選擇的是HE-AAC編碼,在編碼之后的文件信息里面顯示的卻是下面這些內(nèi)容的原因了:

          Codec : AAC LC-SBR
          Codec/Info : AAC Low Complexity with Spectral Band Replication

          根據(jù)Adobe公布的信息,F(xiàn)lash Player支持這些AAC編碼:AAC Main; AAC LC; SBR ,因此,我一般選擇使用NERO Encoder的HE-AAC

          參考鏈接

          1. http://bbs.lmtw.com/dispbbs.asp?boardID=111&ID=141583&page=1
          2. http://mediacoder.sourceforge.net/index_zh.htm
          3. http://www.sxzkw.com/1Qm/MediaCoder_jiaocheng_cn.swf
          4. http://www.adobe.com/devnet/flashplayer/articles/http://www.adobe.com/devnet/flashplayer/articles/hd_video_flash_player.html
          5. http://tech.163.com/05/0624/11/1N0Q0HJ800091589.html
          6. http://kb.adobe.com/selfservice/viewContent.do?externalId=kb402866&sliceId=1
          posted @ 2008-12-23 17:44 小馬歌 閱讀(875) | 評論 (0)編輯 收藏
           

          用 MEncoder 編碼 H. 264 流
          In Mac, Miscs, Tools on 9 July 2008 tagged h264, mencoder with no comments

          MEncoder 是常用的離線編碼器,屬于 mplayer 項目的一部分,這里介紹了怎樣用 MEncoder 編碼常見的視頻流。

          首先,要安裝 x264 編碼庫,mplayer 需要這個庫才能加上 H. 264 編碼支持:


          $ git clone git://git.videolan.org/x264.git
          $ cd x264
          $ ./configure
          $ make && sudo make install


          注意 x264 庫需要 yasm 匯編器,MacPorts 下可以用 sudo port install yasm 安裝。

          然后編譯 mplayer (包括 mencoder)。


          $ svn co svn://svn.mplayerhq.hu/mplayer/trunk mplayer
          $ cd mplayer
          $ ./configure # 注意輸出中是否有 "Checking for x264 ... yes" 字樣
          $ make && sudo make install


          然后就可以調(diào)用 MEncoder 了:


          $ mencoder input.fmt -o output.fmt -ovc x264 -oac copy -x264encopts \
              bframes=4:b_pyramid:weight_b:pass=1:psnr:bitrate=1500:turbo=1


          其中 input.fmt, output.fmt 分別是輸入和輸出文件,其調(diào)用格式見 MEncoder 的文檔,而后面 -x264encopts 的參數(shù)制定的是 x264 編碼參數(shù),這是影響編碼質(zhì)量和速度的地方,文檔中也有專門一節(jié)詳細(xì)說明,這里選取的是一個中等偏上的效果。

          posted @ 2008-12-22 14:55 小馬歌 閱讀(1004) | 評論 (0)編輯 收藏
           
          下載最新的svn壓縮包http://subversion.tigris.org/downloads/subversion-1.4.5.tar.gz
          //解壓SubVersion安裝包 (root用戶進行下面的操作) # tar xvzf subversion-1.4.5.tar.gz

          //進入解壓后的目錄

          # cd Subversion-1.4.5

          //配置subversion安裝

          #./configure --with-apxs=/usr/local/apache2/bin/apxs --prefix=/usr/local/subversion
          --with-apr=/usr/local/apache2 --with-apr-util=/usr/local/apache2 --with-ssl --with-zlib
          --enable-maintainer-mode
          # make

          //安裝

          # make install

          //創(chuàng)建庫文件所在的目錄 (svnroot用戶進行下面的操作)

          # mkdir /home/svnroot/repository

          //進入subversion的bin目錄

          # cd /usr/local/subversion/bin

          //創(chuàng)建倉庫"test"

          # ./svnadmin create /home/svnroot/repository/test
          # cd /home/svnroot/repository/test

          //看看是不是多了些文件,如果是則說明Subversion安裝成功了

          # ls –l
          # cd /usr/local/subversion/bin

          //這條語句將把路徑/home/user/import下找到的文件導(dǎo)入到你創(chuàng)建的Subversion 倉庫中去,
          //提交后的修訂版為1。

          # ./svn import /home/user/import file:///home/svnroot/repository/test –m "注釋"

          修改Apache配置文件
          # cd /usr/local/apadche2/bin
          //啟動Apache
          # ./apachect1 start
          # vi /usr/local/apache2/conf/httpd.conf
          //在最下面添加
          LoadModule dav_svn_module modules/mod_dav_svn.so
          LoadModule authz_svn_module modules/mod_authz_svn.so
          <Location /svn>
          DAV svn
          SVNParentPath /home/svnroot/repository/ //svn父目錄
          AuthzSVNAccessFile /home/svnroot/repository/authz.conf //權(quán)限配置文件
          AuthType Basic //連接類型設(shè)置
          AuthName "Subversion.zoneyump" //連接框提示
          AuthUserFile /home/svnroot/repository/authfile //用戶配置文件
          Require valid-user //采用何種認(rèn)證
          </Location>

          //其中authfile是通過"htpasswd [–c] /home/svnroot/repository/authfile username password"來創(chuàng)建的
          //"Require valid-user"告訴apache在authfile中所有的用戶都可以訪問。如果沒有它,
          //則只能第一個用戶可以訪問新建庫

          6. 權(quán)限管理
          1)增加用戶
          # htpasswd [-c] /home/svnroot/repository/authfile wooin
          //第一次設(shè)置用戶時使用-c表示新建一個用戶文件。回車后輸入用戶密碼,完成對用戶的增加
          # htpasswd authfile 用戶名(加入新的用戶)

          2)權(quán)限分配
          # vi /home/svnroot/repository/authz.conf
          [test:/] //這表示,倉庫test的根目錄下的訪問權(quán)限
          wooin = rw //test倉庫wooin用戶具有讀和寫權(quán)限
          bao = r //test倉庫bao用戶具有讀權(quán)限
          [test2:/] //test2倉庫根目錄下的訪問權(quán)限
          wooin = r //wooin用戶在test2倉庫根目錄下只有讀權(quán)限
          bao = //bao用戶在 test2倉庫根目錄下無任何權(quán)限
          [/] //這個表示在所有倉庫的根目錄下
          * = r //這個表示對所有的用戶都具有讀權(quán)限
          #[groups] //這個表示群組設(shè)置
          #svn1-developers = wooin, bao //這個表示某群組里的成員
          #svn2-developers = wooin
          #[svn1:/]
          #@svn1-developers = rw //如果在前面加上@符號,則表示這是個群組權(quán)限設(shè)置


          將這個設(shè)置完成后。重啟Apache,就可以通過
          http://localhost/svn/test
          這個URL來訪問倉庫了,當(dāng)然,受權(quán)限的限制,必須是合法用戶才能訪問且具有相應(yīng)的權(quán)限
          posted @ 2008-12-18 15:21 小馬歌 閱讀(206) | 評論 (0)編輯 收藏
           

          在1.0的時候是好使的 換成2.0的時候
          就出現(xiàn) Missing method or missing parameter converters 這個錯誤了

          2007-11-29 17:44:14 org.directwebremoting.util.CommonsLoggingOutput warn

          警告: Marshalling exception: Missing method or missing parameter converters:

          主要原因就是DWR2中更新了的內(nèi)容,原文如下:

          The callback-as-first-parameter system has been deprecated since version 0.9 in favor of the callback-as-last-parameter system. In version 2.0 we removed support for the first-parameter option because it caused some hard to detect bugs with null parameters. From version 2.0 the callback must be the last parameter, and can not be the first parameter.

          就是說以前版本callback參數(shù)是放在參數(shù)列表第一個參數(shù),而在0.9版本中callback參數(shù)改為參數(shù)列表最后一個參數(shù)。到2.0版本取消了對callback參數(shù)前置的支持。



          說明:dwr1.0本身解析器就有點問題,所以推薦 要有dwr2.0.
          posted @ 2008-12-16 14:48 小馬歌 閱讀(254) | 評論 (0)編輯 收藏
           
          進入測試環(huán)境:
          代碼:
          @echo off
          echo proj 本地測試環(huán)境
          echo.
          c:
          cd \
          if not exist proj-test\con md proj-test
          if exist proj-test\hosts.bak goto backup_exists
          echo 正在創(chuàng)建備份……
          cd \windows\system32\drivers\etc
          copy /y hosts \proj-test\hosts.bak > null
          echo 完成!
          echo.
          goto backup_start
          :backup_exists
          echo 備份文件已經(jīng)存在,無需備份。
          echo.
          :backup_start
          echo 正在寫入測試數(shù)據(jù)……
          echo 127.0.0.1       localhost > hosts
          echo 192.168.3.170   proj.com >> hosts
          echo 192.168.3.170   www.proj.com >> hosts
          echo 192.168.3.170   pics.proj.com >> hosts
          echo 192.168.3.170   files.proj.com >> hosts
          echo 完成!
          echo.
          echo 建立 proj 本地測試環(huán)境完成。按任意鍵退出……
          pause > null
          退出測試環(huán)境:
          代碼:
          @echo off
          echo proj 本地測試環(huán)境
          echo.
          c:
          cd \
          if not exist proj-test\hosts.bak goto backup_not_exists
          echo 正在還原備份……
          copy /y \proj-test\hosts.bak \windows\system32\drivers\etc > null
          cd \windows\system32\drivers\etc
          if exist hosts del /q hosts
          ren hosts.bak hosts
          echo 完成!
          echo.
          echo 正在移除備份……
          cd \
          rmdir /s/q \proj-test\
          echo 完成!
          echo.
          goto backup_done
          :backup_not_exists
          echo 備份文件不存在,無法恢復(fù)。
          echo.
          :backup_done
          echo 退出 proj 本地測試環(huán)境完成。按任意鍵退出……
          pause > null
          posted @ 2008-12-15 18:22 小馬歌 閱讀(4036) | 評論 (3)編輯 收藏
           
          作者:肖文鵬 發(fā)文時間:2004.03.22
          在為Linux開發(fā)應(yīng)用程序時,絕大多數(shù)情況下使用的都是C語言,因此幾乎每一位Linux程序員面臨的首要問題都是如何靈活運用C編譯器。目前Linux下最常用的C語言編譯器是GCC(GNU Compiler Collection),它是GNU項目中符合ANSI C標(biāo)準(zhǔn)的編譯系統(tǒng),能夠編譯用C、C++和Object C等語言編寫的程序。GCC不僅功能非常強大,結(jié)構(gòu)也異常靈活。最值得稱道的一點就是它可以通過不同的前端模塊來支持各種語言,如Java、Fortran、Pascal、Modula-3和Ada等。

          開放、自由和靈活是Linux的魅力所在,而這一點在GCC上的體現(xiàn)就是程序員通過它能夠更好地控制整個編譯過程。在使用GCC編譯程序時,編譯過程可以被細(xì)分為四個階段:

          ◆ 預(yù)處理(Pre-Processing)

          ◆ 編譯(Compiling)

          ◆ 匯編(Assembling)

          ◆ 鏈接(Linking)

          Linux程序員可以根據(jù)自己的需要讓GCC在編譯的任何階段結(jié)束,以便檢查或使用編譯器在該階段的輸出信息,或者對最后生成的二進制文件進行控制,以便通過加入不同數(shù)量和種類的調(diào)試代碼來為今后的調(diào)試做好準(zhǔn)備。和其它常用的編譯器一樣,GCC也提供了靈活而強大的代碼優(yōu)化功能,利用它可以生成執(zhí)行效率更高的代碼。

          GCC提供了30多條警告信息和三個警告級別,使用它們有助于增強程序的穩(wěn)定性和可移植性。此外,GCC還對標(biāo)準(zhǔn)的C和C++語言進行了大量的擴展,提高程序的執(zhí)行效率,有助于編譯器進行代碼優(yōu)化,能夠減輕編程的工作量。

          GCC起步

          在學(xué)習(xí)使用GCC之前,下面的這個例子能夠幫助用戶迅速理解GCC的工作原理,并將其立即運用到實際的項目開發(fā)中去。首先用熟悉的編輯器輸入清單1所示的代碼:

          清單1:hello.c

           #include <stdio.h>
           int main(void)
           {
            printf ("Hello world, Linux programming!\n");
            return 0;
           }
           
          然后執(zhí)行下面的命令編譯和運行這段程序:

           # gcc hello.c -o hello # ./hello Hello world, Linux programming!
           
          從程序員的角度看,只需簡單地執(zhí)行一條GCC命令就可以了,但從編譯器的角度來看,卻需要完成一系列非常繁雜的工作。首先,GCC需要調(diào)用預(yù)處理程序cpp,由它負(fù)責(zé)展開在源文件中定義的宏,并向其中插入“#include”語句所包含的內(nèi)容;接著,GCC會調(diào)用ccl和as將處理后的源代碼編譯成目標(biāo)代碼;最后,GCC會調(diào)用鏈接程序ld,把生成的目標(biāo)代碼鏈接成一個可執(zhí)行程序。

          為了更好地理解GCC的工作過程,可以把上述編譯過程分成幾個步驟單獨進行,并觀察每步的運行結(jié)果。第一步是進行預(yù)編譯,使用-E參數(shù)可以讓GCC在預(yù)處理結(jié)束后停止編譯過程:

           # gcc -E hello.c -o hello.i
           
          此時若查看hello.cpp文件中的內(nèi)容,會發(fā)現(xiàn)stdio.h的內(nèi)容確實都插到文件里去了,而其它應(yīng)當(dāng)被預(yù)處理的宏定義也都做了相應(yīng)的處理。下一步是將hello.i編譯為目標(biāo)代碼,這可以通過使用-c參數(shù)來完成:

           # gcc -c hello.i -o hello.o
           
          GCC默認(rèn)將.i文件看成是預(yù)處理后的C語言源代碼,因此上述命令將自動跳過預(yù)處理步驟而開始執(zhí)行編譯過程,也可以使用-x參數(shù)讓GCC從指定的步驟開始編譯。最后一步是將生成的目標(biāo)文件鏈接成可執(zhí)行文件:

           # gcc hello.o -o hello
           
          在采用模塊化的設(shè)計思想進行軟件開發(fā)時,通常整個程序是由多個源文件組成的,相應(yīng)地也就形成了多個編譯單元,使用GCC能夠很好地管理這些編譯單元。假設(shè)有一個由foo1.c和foo2.c兩個源文件組成的程序,為了對它們進行編譯,并最終生成可執(zhí)行程序foo,可以使用下面這條命令:

           # gcc foo1.c foo2.c -o foo
           
          如果同時處理的文件不止一個,GCC仍然會按照預(yù)處理、編譯和鏈接的過程依次進行。如果深究起來,上面這條命令大致相當(dāng)于依次執(zhí)行如下三條命令:

           # gcc -c foo1.c -o foo1.o # gcc -c foo2.c -o foo2.o # gcc foo1.o foo2.o -o foo
           
          在編譯一個包含許多源文件的工程時,若只用一條GCC命令來完成編譯是非常浪費時間的。假設(shè)項目中有100個源文件需要編譯,并且每個源文件中都包含10000行代碼,如果像上面那樣僅用一條GCC命令來完成編譯工作,那么GCC需要將每個源文件都重新編譯一遍,然后再全部連接起來。很顯然,這樣浪費的時間相當(dāng)多,尤其是當(dāng)用戶只是修改了其中某一個文件的時候,完全沒有必要將每個文件都重新編譯一遍,因為很多已經(jīng)生成的目標(biāo)文件是不會改變的。要解決這個問題,關(guān)鍵是要靈活運用GCC,同時還要借助像Make這樣的工具。

          警告提示功能

          GCC包含完整的出錯檢查和警告提示功能,它們可以幫助Linux程序員寫出更加專業(yè)和優(yōu)美的代碼。先來讀讀清單2所示的程序,這段代碼寫得很糟糕,仔細(xì)檢查一下不難挑出很多毛病:

          ◆main函數(shù)的返回值被聲明為void,但實際上應(yīng)該是int;

          ◆使用了GNU語法擴展,即使用long long來聲明64位整數(shù),不符合ANSI/ISO C語言標(biāo)準(zhǔn);

          ◆main函數(shù)在終止前沒有調(diào)用return語句。

          清單2:illcode.c

           #include <stdio.h>
           void main(void)
           {
            long long int var = 1;
            printf("It is not standard C code!\n");
           }

          下面來看看GCC是如何幫助程序員來發(fā)現(xiàn)這些錯誤的。當(dāng)GCC在編譯不符合ANSI/ISO C語言標(biāo)準(zhǔn)的源代碼時,如果加上了-pedantic選項,那么使用了擴展語法的地方將產(chǎn)生相應(yīng)的警告信息:

           # gcc -pedantic illcode.c -o illcode illcode.c: In function `main': illcode.c:9: ISO C89 does not support `long long' illcode.c:8: return type of `main' is not `int'

          需要注意的是,-pedantic編譯選項并不能保證被編譯程序與ANSI/ISO C標(biāo)準(zhǔn)的完全兼容,它僅僅只能用來幫助Linux程序員離這個目標(biāo)越來越近。或者換句話說,-pedantic選項能夠幫助程序員發(fā)現(xiàn)一些不符合ANSI/ISO C標(biāo)準(zhǔn)的代碼,但不是全部,事實上只有ANSI/ISO C語言標(biāo)準(zhǔn)中要求進行編譯器診斷的那些情況,才有可能被GCC發(fā)現(xiàn)并提出警告。

          除了-pedantic之外,GCC還有一些其它編譯選項也能夠產(chǎn)生有用的警告信息。這些選項大多以-W開頭,其中最有價值的當(dāng)數(shù)-Wall了,使用它能夠使GCC產(chǎn)生盡可能多的警告信息:

           # gcc -Wall illcode.c -o illcode illcode.c:8: warning: return type of `main' is not `int' illcode.c: In function `main': illcode.c:9: warning: unused variable `var'

          GCC給出的警告信息雖然從嚴(yán)格意義上說不能算作是錯誤,但卻很可能成為錯誤的棲身之所。一個優(yōu)秀的Linux程序員應(yīng)該盡量避免產(chǎn)生警告信息,使自己的代碼始終保持簡潔、優(yōu)美和健壯的特性

          在處理警告方面,另一個常用的編譯選項是-Werror,它要求GCC將所有的警告當(dāng)成錯誤進行處理,這在使用自動編譯工具(如Make等)時非常有用。如果編譯時帶上-Werror選項,那么GCC會在所有產(chǎn)生警告的地方停止編譯,迫使程序員對自己的代碼進行修改。只有當(dāng)相應(yīng)的警告信息消除時,才可能將編譯過程繼續(xù)朝前推進。執(zhí)行情況如下:

           # gcc -Wall -Werror illcode.c -o illcode cc1: warnings being treated as errors illcode.c:8: warning: return type of `main' is not `int' illcode.c: In function `main': illcode.c:9: warning: unused variable `var'

          對Linux程序員來講,GCC給出的警告信息是很有價值的,它們不僅可以幫助程序員寫出更加健壯的程序,而且還是跟蹤和調(diào)試程序的有力工具。建議在用GCC編譯源代碼時始終帶上-Wall選項,并把它逐漸培養(yǎng)成為一種習(xí)慣,這對找出常見的隱式編程錯誤很有幫助。

          庫依賴

          在Linux下開發(fā)軟件時,完全不使用第三方函數(shù)庫的情況是比較少見的,通常來講都需要借助一個或多個函數(shù)庫的支持才能夠完成相應(yīng)的功能。從程序員的角度看,函數(shù)庫實際上就是一些頭文件(.h)和庫文件(.so或者.a)的集合。雖然Linux下的大多數(shù)函數(shù)都默認(rèn)將頭文件放到/usr/include/目錄下,而庫文件則放到/usr/lib/目錄下,但并不是所有的情況都是這樣。正因如此,GCC在編譯時必須有自己的辦法來查找所需要的頭文件和庫文件。

          GCC采用搜索目錄的辦法來查找所需要的文件,-I選項可以向GCC的頭文件搜索路徑中添加新的目錄。例如,如果在/home/xiaowp/include/目錄下有編譯時所需要的頭文件,為了讓GCC能夠順利地找到它們,就可以使用-I選項:

           # gcc foo.c -I /home/xiaowp/include -o foo

          同樣,如果使用了不在標(biāo)準(zhǔn)位置的庫文件,那么可以通過-L選項向GCC的庫文件搜索路徑中添加新的目錄。例如,如果在/home/xiaowp/lib/目錄下有鏈接時所需要的庫文件libfoo.so,為了讓GCC能夠順利地找到它,可以使用下面的命令:

           # gcc foo.c -L /home/xiaowp/lib -lfoo -o foo

          值得好好解釋一下的是-l選項,它指示GCC去連接庫文件libfoo.so。Linux下的庫文件在命名時有一個約定,那就是應(yīng)該以lib三個字母開頭,由于所有的庫文件都遵循了同樣的規(guī)范,因此在用-l選項指定鏈接的庫文件名時可以省去lib三個字母,也就是說GCC在對-lfoo進行處理時,會自動去鏈接名為libfoo.so的文件。

          Linux下的庫文件分為兩大類分別是動態(tài)鏈接庫(通常以.so結(jié)尾)和靜態(tài)鏈接庫(通常以.a結(jié)尾),兩者的差別僅在程序執(zhí)行時所需的代碼是在運行時動態(tài)加載的,還是在編譯時靜態(tài)加載的。默認(rèn)情況下,GCC在鏈接時優(yōu)先使用動態(tài)鏈接庫,只有當(dāng)動態(tài)鏈接庫不存在時才考慮使用靜態(tài)鏈接庫,如果需要的話可以在編譯時加上-static選項,強制使用靜態(tài)鏈接庫。例如,如果在/home/xiaowp/lib/目錄下有鏈接時所需要的庫文件libfoo.so和libfoo.a,為了讓GCC在鏈接時只用到靜態(tài)鏈接庫,可以使用下面的命令:

           # gcc foo.c -L /home/xiaowp/lib -static -lfoo -o foo
           
          代碼優(yōu)化

          代碼優(yōu)化指的是編譯器通過分析源代碼,找出其中尚未達到最優(yōu)的部分,然后對其重新進行組合,目的是改善程序的執(zhí)行性能。GCC提供的代碼優(yōu)化功能非常強大,它通過編譯選項-On來控制優(yōu)化代碼的生成,其中n是一個代表優(yōu)化級別的整數(shù)。對于不同版本的GCC來講,n的取值范圍及其對應(yīng)的優(yōu)化效果可能并不完全相同,比較典型的范圍是從0變化到2或3。

          編譯時使用選項-O可以告訴GCC同時減小代碼的長度和執(zhí)行時間,其效果等價于-O1。在這一級別上能夠進行的優(yōu)化類型雖然取決于目標(biāo)處理器,但一般都會包括線程跳轉(zhuǎn)(Thread Jump)和延遲退棧(Deferred Stack Pops)兩種優(yōu)化。選項-O2告訴GCC除了完成所有-O1級別的優(yōu)化之外,同時還要進行一些額外的調(diào)整工作,如處理器指令調(diào)度等。選項-O3則除了完成所有-O2級別的優(yōu)化之外,還包括循環(huán)展開和其它一些與處理器特性相關(guān)的優(yōu)化工作。通常來說,數(shù)字越大優(yōu)化的等級越高,同時也就意味著程序的運行速度越快。許多Linux程序員都喜歡使用-O2選項,因為它在優(yōu)化長度、編譯時間和代碼大小之間,取得了一個比較理想的平衡點。

          下面通過具體實例來感受一下GCC的代碼優(yōu)化功能,所用程序如清單3所示。

          清單3:optimize.c

           #include <stdio.h>
           int main(void)
           {
            double counter;
            double result;
            double temp;
            
            for (counter = 0; counter < 2000.0 * 2000.0 * 2000.0 / 20.0 + 2020; counter += (5 - 1) / 4)
            {
              temp = counter / 1979; result = counter;
            }
            printf("Result is %lf\n", result); return 0;
           }

          首先不加任何優(yōu)化選項進行編譯:

           # gcc -Wall optimize.c -o optimize
           
          借助Linux提供的time命令,可以大致統(tǒng)計出該程序在運行時所需要的時間:

           # time ./optimize Result is 400002019.000000 real 0m14.942s user 0m14.940s sys 0m0.000s
           
          接下去使用優(yōu)化選項來對代碼進行優(yōu)化處理:

           # gcc -Wall -O optimize.c -o optimize
           
          在同樣的條件下再次測試一下運行時間:

           # time ./optimize Result is 400002019.000000 real 0m3.256s user 0m3.240s sys 0m0.000s
           
          對比兩次執(zhí)行的輸出結(jié)果不難看出,程序的性能的確得到了很大幅度的改善,由原來的14秒縮短到了3秒。這個例子是專門針對GCC的優(yōu)化功能而設(shè)計的,因此優(yōu)化前后程序的執(zhí)行速度發(fā)生了很大的改變。盡管GCC的代碼優(yōu)化功能非常強大,但作為一名優(yōu)秀的Linux程序員,首先還是要力求能夠手工編寫出高質(zhì)量的代碼。如果編寫的代碼簡短,并且邏輯性強,編譯器就不會做更多的工作,甚至根本用不著優(yōu)化。

          優(yōu)化雖然能夠給程序帶來更好的執(zhí)行性能,但在如下一些場合中應(yīng)該避免優(yōu)化代碼:

          ◆ 程序開發(fā)的時候 優(yōu)化等級越高,消耗在編譯上的時間就越長,因此在開發(fā)的時候最好不要使用優(yōu)化選項,只有到軟件發(fā)行或開發(fā)結(jié)束的時候,才考慮對最終生成的代碼進行優(yōu)化。

          ◆ 資源受限的時候 一些優(yōu)化選項會增加可執(zhí)行代碼的體積,如果程序在運行時能夠申請到的內(nèi)存資源非常緊張(如一些實時嵌入式設(shè)備),那就不要對代碼進行優(yōu)化,因為由這帶來的負(fù)面影響可能會產(chǎn)生非常嚴(yán)重的后果。

          ◆ 跟蹤調(diào)試的時候 在對代碼進行優(yōu)化的時候,某些代碼可能會被刪除或改寫,或者為了取得更佳的性能而進行重組,從而使跟蹤和調(diào)試變得異常困難。

          調(diào)試

          一個功能強大的調(diào)試器不僅為程序員提供了跟蹤程序執(zhí)行的手段,而且還可以幫助程序員找到解決問題的方法。對于Linux程序員來講,GDB(GNU Debugger)通過與GCC的配合使用,為基于Linux的軟件開發(fā)提供了一個完善的調(diào)試環(huán)境。

          默認(rèn)情況下,GCC在編譯時不會將調(diào)試符號插入到生成的二進制代碼中,因為這樣會增加可執(zhí)行文件的大小。如果需要在編譯時生成調(diào)試符號信息,可以使用GCC的-g或者-ggdb選項。GCC在產(chǎn)生調(diào)試符號時,同樣采用了分級的思路,開發(fā)人員可以通過在-g選項后附加數(shù)字1、2或3來指定在代碼中加入調(diào)試信息的多少。默認(rèn)的級別是2(-g2),此時產(chǎn)生的調(diào)試信息包括擴展的符號表、行號、局部或外部變量信息。級別3(-g3)包含級別2中的所有調(diào)試信息,以及源代碼中定義的宏。級別1(-g1)不包含局部變量和與行號有關(guān)的調(diào)試信息,因此只能夠用于回溯跟蹤和堆棧轉(zhuǎn)儲之用。回溯跟蹤指的是監(jiān)視程序在運行過程中的函數(shù)調(diào)用歷史,堆棧轉(zhuǎn)儲則是一種以原始的十六進制格式保存程序執(zhí)行環(huán)境的方法,兩者都是經(jīng)常用到的調(diào)試手段。

          GCC產(chǎn)生的調(diào)試符號具有普遍的適應(yīng)性,可以被許多調(diào)試器加以利用,但如果使用的是GDB,那么還可以通過-ggdb選項在生成的二進制代碼中包含GDB專用的調(diào)試信息。這種做法的優(yōu)點是可以方便GDB的調(diào)試工作,但缺點是可能導(dǎo)致其它調(diào)試器(如DBX)無法進行正常的調(diào)試。選項-ggdb能夠接受的調(diào)試級別和-g是完全一樣的,它們對輸出的調(diào)試符號有著相同的影響。

          需要注意的是,使用任何一個調(diào)試選項都會使最終生成的二進制文件的大小急劇增加,同時增加程序在執(zhí)行時的開銷,因此調(diào)試選項通常僅在軟件的開發(fā)和調(diào)試階段使用。調(diào)試選項對生成代碼大小的影響從下面的對比過程中可以看出來:

           # gcc optimize.c -o optimize # ls optimize -l -rwxrwxr-x 1 xiaowp xiaowp 11649 Nov 20 08:53 optimize (未加調(diào)試選項) # gcc -g optimize.c -o optimize # ls optimize -l -rwxrwxr-x 1 xiaowp xiaowp 15889 Nov 20 08:54 optimize (加入調(diào)試選項)
           
          雖然調(diào)試選項會增加文件的大小,但事實上Linux中的許多軟件在測試版本甚至最終發(fā)行版本中仍然使用了調(diào)試選項來進行編譯,這樣做的目的是鼓勵用戶在發(fā)現(xiàn)問題時自己動手解決,是Linux的一個顯著特色。

          下面還是通過一個具體的實例說明如何利用調(diào)試符號來分析錯誤,所用程序見清單4所示。

          清單4:crash.c

           #include <stdio.h>
           int main(void)
           {
            int input =0;
            
            printf("Input an integer:");
            scanf("%d", input);
            printf("The integer you input is %d\n", input);
            return 0;
           }
           
          編譯并運行上述代碼,會產(chǎn)生一個嚴(yán)重的段錯誤(Segmentation fault)如下:

           # gcc -g crash.c -o crash # ./crash Input an integer:10 Segmentation fault
           
          為了更快速地發(fā)現(xiàn)錯誤所在,可以使用GDB進行跟蹤調(diào)試,方法如下:

           # gdb crash GNU gdb Red Hat Linux (5.3post-0.20021129.18rh) …… (gdb)
           
          當(dāng)GDB提示符出現(xiàn)的時候,表明GDB已經(jīng)做好準(zhǔn)備進行調(diào)試了,現(xiàn)在可以通過run命令讓程序開始在GDB的監(jiān)控下運行:

           (gdb) run Starting program: /home/xiaowp/thesis/gcc/code/crash Input an integer:10 Program received signal SIGSEGV, Segmentation fault. 0x4008576b in _IO_vfscanf_internal () from /lib/libc.so.6
           
          仔細(xì)分析一下GDB給出的輸出結(jié)果不難看出,程序是由于段錯誤而導(dǎo)致異常中止的,說明內(nèi)存操作出了問題,具體發(fā)生問題的地方是在調(diào)用_IO_vfscanf_internal ( )的時候。為了得到更加有價值的信息,可以使用GDB提供的回溯跟蹤命令backtrace,執(zhí)行結(jié)果如下:

           (gdb) backtrace #0 0x4008576b in _IO_vfscanf_internal () from /lib/libc.so.6 #1 0xbffff0c0 in ?? () #2 0x4008e0ba in scanf () from /lib/libc.so.6 #3 0x08048393 in main () at crash.c:11 #4 0x40042917 in __libc_start_main () from /lib/libc.so.6
           
          跳過輸出結(jié)果中的前面三行,從輸出結(jié)果的第四行中不難看出,GDB已經(jīng)將錯誤定位到crash.c中的第11行了。現(xiàn)在仔細(xì)檢查一下:

           (gdb) frame 3 #3 0x08048393 in main () at crash.c:11 11 scanf("%d", input);
           
          使用GDB提供的frame命令可以定位到發(fā)生錯誤的代碼段,該命令后面跟著的數(shù)值可以在backtrace命令輸出結(jié)果中的行首找到。現(xiàn)在已經(jīng)發(fā)現(xiàn)錯誤所在了,應(yīng)該將

           scanf("%d", input); 改為 scanf("%d", &input);
           
          完成后就可以退出GDB了,命令如下:

           (gdb) quit
           
          GDB的功能遠遠不止如此,它還可以單步跟蹤程序、檢查內(nèi)存變量和設(shè)置斷點等。

          調(diào)試時可能會需要用到編譯器產(chǎn)生的中間結(jié)果,這時可以使用-save-temps選項,讓GCC將預(yù)處理代碼、匯編代碼和目標(biāo)代碼都作為文件保存起來。如果想檢查生成的代碼是否能夠通過手工調(diào)整的辦法來提高執(zhí)行性能,在編譯過程中生成的中間文件將會很有幫助,具體情況如下:

           # gcc -save-temps foo.c -o foo # ls foo* foo foo.c foo.i foo.s
           
          GCC支持的其它調(diào)試選項還包括-p和-pg,它們會將剖析(Profiling)信息加入到最終生成的二進制代碼中。剖析信息對于找出程序的性能瓶頸很有幫助,是協(xié)助Linux程序員開發(fā)出高性能程序的有力工具。在編譯時加入-p選項會在生成的代碼中加入通用剖析工具(Prof)能夠識別的統(tǒng)計信息,而-pg選項則生成只有GNU剖析工具(Gprof)才能識別的統(tǒng)計信息。

          最后提醒一點,雖然GCC允許在優(yōu)化的同時加入調(diào)試符號信息,但優(yōu)化后的代碼對于調(diào)試本身而言將是一個很大的挑戰(zhàn)。代碼在經(jīng)過優(yōu)化之后,在源程序中聲明和使用的變量很可能不再使用,控制流也可能會突然跳轉(zhuǎn)到意外的地方,循環(huán)語句有可能因為循環(huán)展開而變得到處都有,所有這些對調(diào)試來講都將是一場噩夢。建議在調(diào)試的時候最好不使用任何優(yōu)化選項,只有當(dāng)程序在最終發(fā)行的時候才考慮對其進行優(yōu)化。

          上次的培訓(xùn)園地中介紹了GCC的編譯過程、警告提示功能、庫依賴、代碼優(yōu)化和程序調(diào)試六個方面的內(nèi)容。這期是最后的一部分內(nèi)容。

          加速

          在將源代碼變成可執(zhí)行文件的過程中,需要經(jīng)過許多中間步驟,包含預(yù)處理、編譯、匯編和連接。這些過程實際上是由不同的程序負(fù)責(zé)完成的。大多數(shù)情況下GCC可以為Linux程序員完成所有的后臺工作,自動調(diào)用相應(yīng)程序進行處理。

          這樣做有一個很明顯的缺點,就是GCC在處理每一個源文件時,最終都需要生成好幾個臨時文件才能完成相應(yīng)的工作,從而無形中導(dǎo)致處理速度變慢。例如,GCC在處理一個源文件時,可能需要一個臨時文件來保存預(yù)處理的輸出、一個臨時文件來保存編譯器的輸出、一個臨時文件來保存匯編器的輸出,而讀寫這些臨時文件顯然需要耗費一定的時間。當(dāng)軟件項目變得非常龐大的時候,花費在這上面的代價可能會變得很沉重。

          解決的辦法是,使用Linux提供的一種更加高效的通信方式—管道。它可以用來同時連接兩個程序,其中一個程序的輸出將被直接作為另一個程序的輸入,這樣就可以避免使用臨時文件,但編譯時卻需要消耗更多的內(nèi)存。

          在編譯過程中使用管道是由GCC的-pipe選項決定的。下面的這條命令就是借助GCC的管道功能來提高編譯速度的:

           # gcc -pipe foo.c -o foo
           
          在編譯小型工程時使用管道,編譯時間上的差異可能還不是很明顯,但在源代碼非常多的大型工程中,差異將變得非常明顯。

          文件擴展名

          在使用GCC的過程中,用戶對一些常用的擴展名一定要熟悉,并知道其含義。為了方便大家學(xué)習(xí)使用GCC,在此將這些擴展名羅列如下:

          .c C原始程序;

          .C C++原始程序;

          .cc C++原始程序;

          .cxx C++原始程序;

          .m Objective-C原始程序;

          .i 已經(jīng)過預(yù)處理的C原始程序;

          .ii 已經(jīng)過預(yù)處理之C++原始程序;

          .s 組合語言原始程序;

          .S 組合語言原始程序;

          .h 預(yù)處理文件(標(biāo)頭文件);

          .o 目標(biāo)文件;

          .a 存檔文件。

          GCC常用選項

          GCC作為Linux下C/C++重要的編譯環(huán)境,功能強大,編譯選項繁多。為了方便大家日后編譯方便,在此將常用的選項及說明羅列出來如下:

          -c 通知GCC取消鏈接步驟,即編譯源碼并在最后生成目標(biāo)文件;

          -Dmacro 定義指定的宏,使它能夠通過源碼中的#ifdef進行檢驗;

          -E 不經(jīng)過編譯預(yù)處理程序的輸出而輸送至標(biāo)準(zhǔn)輸出;

          -g3 獲得有關(guān)調(diào)試程序的詳細(xì)信息,它不能與-o選項聯(lián)合使用;

          -Idirectory 在包含文件搜索路徑的起點處添加指定目錄;

          -llibrary 提示鏈接程序在創(chuàng)建最終可執(zhí)行文件時包含指定的庫;

          -O、-O2、-O3 將優(yōu)化狀態(tài)打開,該選項不能與-g選項聯(lián)合使用;

          -S 要求編譯程序生成來自源代碼的匯編程序輸出;

          -v 啟動所有警報;

          -Wall 在發(fā)生警報時取消編譯操作,即將警報看作是錯誤;

          -Werror 在發(fā)生警報時取消編譯操作,即把報警當(dāng)作是錯誤;

          -w 禁止所有的報警。

          小結(jié)

          GCC是在Linux下開發(fā)程序時必須掌握的工具之一。本文對GCC做了一個簡要的介紹,主要講述了如何使用GCC編譯程序、產(chǎn)生警告信息、調(diào)試程序和加快GCC的編譯速度。對所有希望早日跨入Linux開發(fā)者行列的人來說,GCC就是成為一名優(yōu)秀的Linux程序員的起跑線。

          posted @ 2008-12-11 16:14 小馬歌 閱讀(89) | 評論 (0)編輯 收藏
           

          來源:http://www.7880.com/Info/Article-33fb30a0.html

          2004年4月20日最新版本的GCC編譯器3.4.0發(fā)布了。目前,GCC可以用來編譯C/C++、FORTRAN、JAVA、OBJC、ADA等語言的程序,可根據(jù)需要選擇安裝支持的語言。GCC 3.4.0比以前版本更好地支持了C++標(biāo)準(zhǔn)。本文以在Redhat Linux上安裝GCC3.4.0為例,介紹了GCC的安裝過程。

            安裝之前,系統(tǒng)中必須要有cc或者gcc等編譯器,并且是可用的,或者用環(huán)境變量CC指定系統(tǒng)上的編譯器。如果系統(tǒng)上沒有編譯器,不能安裝源代碼形式的GCC 3.4.0。如果是這種情況,可以在網(wǎng)上找一個與你系統(tǒng)相適應(yīng)的如RPM等二進制形式的GCC軟件包來安裝使用。本文介紹的是以源代碼形式提供的GCC軟件包的安裝過程,軟件包本身和其安裝過程同樣適用于其它Linux和Unix系統(tǒng)。

            系統(tǒng)上原來的GCC編譯器可能是把gcc等命令文件、庫文件、頭文件等分別存放到系統(tǒng)中的不同目錄下的。與此不同,現(xiàn)在GCC建議我們將一個版本的GCC安裝在一個單獨的目錄下。這樣做的好處是將來不需要它的時候可以方便地刪除整個目錄即可(因為GCC沒有uninstall功能);缺點是在安裝完成后要做一些設(shè)置工作才能使編譯器工作正常。在本文中我采用這個方案安裝GCC 3.4.0,并且在安裝完成后,仍然能夠使用原來低版本的GCC編譯器,即一個系統(tǒng)上可以同時存在并使用多個版本的GCC編譯器。

            按照本文提供的步驟和設(shè)置選項,即使以前沒有安裝過GCC,也可以在系統(tǒng)上安裝上一個可工作的新版本的GCC編譯器。

            1. 下載

            在GCC網(wǎng)站上(http://gcc.gnu.org/)或者通過網(wǎng)上搜索可以查找到下載資源。目前GCC的最新版本為 3.4.0。可供下載的文件一般有兩種形式:gcc-3.4.0.tar.gz和gcc-3.4.0.tar.bz2,只是壓縮格式不一樣,內(nèi)容完全一致,下載其中一種即可。

            2. 解壓縮

            根據(jù)壓縮格式,選擇下面相應(yīng)的一種方式解包(以下的“%”表示命令行提示符):

            % tar xzvf gcc-3.4.0.tar.gz
            或者
            % bzcat gcc-3.4.0.tar.bz2 | tar xvf -

            新生成的gcc-3.4.0這個目錄被稱為源目錄,用${srcdir}表示它。以后在出現(xiàn)${srcdir}的地方,應(yīng)該用真實的路徑來替換它。用pwd命令可以查看當(dāng)前路徑。

            在${srcdir}/INSTALL目錄下有詳細(xì)的GCC安裝說明,可用瀏覽器打開index.html閱讀。

            3. 建立目標(biāo)目錄
           
            目標(biāo)目錄(用${objdir}表示)是用來存放編譯結(jié)果的地方。GCC建議編譯后的文件不要放在源目錄${srcdir]中(雖然這樣做也可以),最好單獨存放在另外一個目錄中,而且不能是${srcdir}的子目錄。

            例如,可以這樣建立一個叫 gcc-build 的目標(biāo)目錄(與源目錄${srcdir}是同級目錄):

            % mkdir gcc-build
            % cd gcc-build

            以下的操作主要是在目標(biāo)目錄 ${objdir} 下進行。

            4. 配置
           
            配置的目的是決定將GCC編譯器安裝到什么地方(${destdir}),支持什么語言以及指定其它一些選項等。其中,${destdir}不能與${objdir}或${srcdir}目錄相同。

            配置是通過執(zhí)行${srcdir}下的configure來完成的。其命令格式為(記得用你的真實路徑替換${destdir}):

            % ${srcdir}/configure --prefix=${destdir} [其它選項]

            例如,如果想將GCC 3.4.0安裝到/usr/local/gcc-3.4.0目錄下,則${destdir}就表示這個路徑。

            在我的機器上,我是這樣配置的:

            % ../gcc-3.4.0/configure --prefix=/usr/local/gcc-3.4.0 --enable-threads=posix --disable-checking --enable--long-long --host=i386-redhat-linux --with-system-zlib --enable-languages=c,c++,java

            將GCC安裝在/usr/local/gcc-3.4.0目錄下,支持C/C++和JAVA語言,其它選項參見GCC提供的幫助說明。

            5. 編譯

            % make

            這是一個漫長的過程。在我的機器上(P4-1.6),這個過程用了50多分鐘。

            6. 安裝

            執(zhí)行下面的命令將編譯好的庫文件等拷貝到${destdir}目錄中(根據(jù)你設(shè)定的路徑,可能需要管理員的權(quán)限):

            % make install

            至此,GCC 3.4.0安裝過程就完成了。

            6. 其它設(shè)置

            GCC 3.4.0的所有文件,包括命令文件(如gcc、g++)、庫文件等都在${destdir}目錄下分別存放,如命令文件放在bin目錄下、庫文件在lib下、頭文件在include下等。由于命令文件和庫文件所在的目錄還沒有包含在相應(yīng)的搜索路徑內(nèi),所以必須要作適當(dāng)?shù)脑O(shè)置之后編譯器才能順利地找到并使用它們。

            6.1 gcc、g++、gcj的設(shè)置

            要想使用GCC 3.4.0的gcc等命令,簡單的方法就是把它的路徑${destdir}/bin放在環(huán)境變量PATH中。我不用這種方式,而是用符號連接的方式實現(xiàn),這樣做的好處是我仍然可以使用系統(tǒng)上原來的舊版本的GCC編譯器。

            首先,查看原來的gcc所在的路徑:

            % which gcc

            在我的系統(tǒng)上,上述命令顯示:/usr/bin/gcc。因此,原來的gcc命令在/usr/bin目錄下。我們可以把GCC 3.4.0中的gcc、g++、gcj等命令在/usr/bin目錄下分別做一個符號連接:

            % cd /usr/bin
            % ln -s ${destdir}/bin/gcc gcc34
            % ln -s ${destdir}/bin/g++ g++34
            % ln -s ${destdir}/bin/gcj gcj34

            這樣,就可以分別使用gcc34、g++34、gcj34來調(diào)用GCC 3.4.0的gcc、g++、gcj完成對C、C++、JAVA程序的編譯了。同時,仍然能夠使用舊版本的GCC編譯器中的gcc、g++等命令。

            6.2 庫路徑的設(shè)置

            將${destdir}/lib路徑添加到環(huán)境變量LD_LIBRARY_PATH中,最好添加到系統(tǒng)的配置文件中,這樣就不必要每次都設(shè)置這個環(huán)境變量了。

            例如,如果GCC 3.4.0安裝在/usr/local/gcc-3.4.0目錄下,在RH Linux下可以直接在命令行上執(zhí)行或者在文件/etc/profile中添加下面一句:

            setenv LD_LIBRARY_PATH /usr/local/gcc-3.4.0/lib:$LD_LIBRARY_PATH

            7. 測試
           
            用新的編譯命令(gcc34、g++34等)編譯你以前的C、C++程序,檢驗新安裝的GCC編譯器是否能正常工作。

            8. 根據(jù)需要,可以刪除或者保留${srcdir}和${objdir}目錄。

          posted @ 2008-12-11 16:13 小馬歌 閱讀(129) | 評論 (0)編輯 收藏
           

          1,lame下低點的版本,比如 lame-3.93.1
          2,x264下載列表:ftp://ftp.videolan.org/pub/videolan/x264/snapshots [每天一個版本]
          3,make版本要3.81以上:ftp://ftp.gnu.org/gnu/
          4,今天在公司編譯ffmpeg,結(jié)果./configure 正常,但是在make的時候出現(xiàn)了下面的錯誤,在網(wǎng)上尋找,居然找到了解決辦法,特轉(zhuǎn)過來作為自己的總結(jié),方便日后查看

          # make
          gcc -DHAVE_AV_CONFIG_H -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -I. -I"/home/yujingtao/soft/ffmpeg" -D_ISOC99_SOURCE -D_POSIX_C_SOURCE=200112 -fasm -std=c99 -fomit-frame-pointer -pthread -g -Wdeclaration-after-statement -Wall -Wno-switch -Wdisabled-optimization -Wpointer-arith -Wredundant-decls -Wcast-qual -Wwrite-strings -O3 -fno-math-errno       -c -o libavdevice/v4l.o libavdevice/v4l.c
          In file included from libavdevice/v4l.c:32:
          /usr/include/linux/videodev.h:55: error: syntax error before "ulong"
          /usr/include/linux/videodev.h:71: error: syntax error before '}' token
          libavdevice/v4l.c: In function `grab_read_header':
          libavdevice/v4l.c:77: error: storage size of 'tuner' isn't known
          libavdevice/v4l.c:141: error: invalid application of `sizeof' to incomplete type `video_tuner'
          libavdevice/v4l.c:148: error: invalid application of `sizeof' to incomplete type `video_tuner'
          libavdevice/v4l.c:77: warning: unused variable `tuner'
          make: *** [libavdevice/v4l.o] 錯誤 1


          vi /usr/include/linux/videodev.h

          查找rangelow, rangehigh;      /* Tuner range */這一行
          把  ulong rangelow, rangehigh;      /* Tuner range */
          改為:
               unsigned long rangelow, rangehigh;      /* Tuner range */

          參考:
          http://www.2hei.net/mt/2008/08/ffmpeg-3gp-install.html

          posted @ 2008-12-10 18:17 小馬歌 閱讀(1009) | 評論 (1)編輯 收藏
          僅列出標(biāo)題
          共95頁: First 上一頁 75 76 77 78 79 80 81 82 83 下一頁 Last 
           
          主站蜘蛛池模板: 达州市| 青阳县| 辛集市| 合肥市| 开鲁县| 霍林郭勒市| 赫章县| 沂源县| 灵宝市| 黑水县| 玉龙| 军事| 靖州| 天峻县| 汉阴县| 左云县| 贡嘎县| 珠海市| 瑞丽市| 济源市| 农安县| 时尚| 盐津县| 邹平县| 姚安县| 二连浩特市| 融水| 崇左市| 玉环县| 营山县| 中超| 益阳市| 定边县| 依安县| 凌云县| 平利县| 泽库县| 房山区| 苗栗市| 大埔区| 中宁县|