目前分類:程式設計 (12)

瀏覽方式: 標題列表 簡短摘要

1. 將驅動程式的INF 檔copy到System32Inf 底下, 將SYS檔copy 到driver 底下,

2. 起動Device Manager 或重開機就會自動安裝

free6d1823 發表在 痞客邦 留言(0) 人氣()

 
步驟:
1. 得到Class的DevInfo handle
HDEVINFO hInfo = SetupDiGetClassDevs(pGuid, NULL, NULL, DIGCF_PRESENT);
2. 找出所有已安裝的驅動程式的資訊. 由devinfo的內容,判斷此devinfo是否是我們想移除的對象.
SP_DEVINFO_DATA devinfo;
SetupDiEnumDeviceInfo(hInfo, nInstance, &devinfo);
3. 呼叫 SetupDiRemoveDevice(hInfo, &devinfo) 移除之.
4. 關閉 DevInfo handle,
SetupDiDestroyDeviceInfoList(hInfo);
 
到裝置管理員看,我們選的驅動程式真的被移除了

free6d1823 發表在 痞客邦 留言(0) 人氣()

辨識CPU 資訊有三種方法
1. 使用組合語言
bool CPUID_supported() {    __try {       _asm {          xor eax, eax          cpuid       }    }    __except (EXCEPTION_EXECUTE_HANDLER) {       return false;    }    return true; } 
2. 由 Registry 讀出
HKEY_LOCAL_MACHINEHARDWAREDESCRIPTIONSystemCentralProcessor
 
3. Platform SDK提供的函式
GetSystemInfo() 及IsProcessorFeaturePresent()
 
詳情請看
 

free6d1823 發表在 痞客邦 留言(0) 人氣()

How to build 64-bits application on WinXP-64 with AMD64 platform?
There are many discussion on the Internet, but seems not have a good one.

I had tried several methods, the following is the closest one, but still has some problems. I write it down for my memorandum.

  • My Hardware: AMD Athlon64 3000+, 1.81GHz, 512MB RAM
    GeForce MX440 with AGP8x
    GA-K8NSC-939
  • OS: Windows XP 64-bits Edition, 2003, Service Pack 1, v.1069
  • Compiler: VC++ 6.0 with SP5
  • SDK:
    • Windows DDK 3790.1830  (for Microsoft Windows Server 2003 SP1)
    • Platform SDK: PSDK-AMD64, 6.0.3734.0 (from Microsoft download)
  • Settings in MSDEV:
    • Tools->Options->Directories:
      • Executable File:
        %PSDK_DIR%/Bin/Win64/AMD64
        %PSDK_DIR%/Bin/Win64/X86/AMD64
      • Include Files:
        %PSDK_DIR%/Include/ATL
        %PSDK_DIR%/Include/MFC
        %PSDK_DIR%/Include/CRT
        %DDK_DIR%/Inc/CRT
        %DDK_DIR%/Inc/WNET
        %VC_DIR%/VC98/Include
      • Library Files:
        %PSDK_DIR%/Lib/AMD64
        %PSDK_DIR%/Lib/AMD64/ATLMFC
        %VC_DIR%/VC98/LIB

        Note 1: I have verified these path settings are the minimum requirement to build a Debug/Release version of project.
        Note 2: %PSDK_DIR% is the folder you installed the Platfoem SDK, so do %DDK_DIR% and %VC_DIR%. They are not represented as environment variables here.
  • Everytime you create a new project, you must modify the following settings:
    • Project->Settings->C/C++
      • Category: General->Debug info: don't select Program Database for Edit and Continue
      • Category: Code Generation->Use run-time library: select (Debug) Multi-Threaded DLL
      • Remove /Gz, /Gm, /GX items in the Project Options box.
    • Project->Settings->Link
      • Add /machine AMD64 to the Project Options box.
      • Remove /pdbtype:sept in the Project Options box.
  • To run the application, you have to copy some DLLs to the application folder or system32 folder.
    • Debug version: copy the dlls in %PSDK_DIR%NoRedistWin64AMD64.
    • Release version: copy the dlls in %PSDK_DIR%redistWin64AMD64.

The above settings just make your project pass compiling and linking. The Release version can execute normally, but the Debug version shows nothing, it hangs and shows nothing. You cannot even trace into the source code because it said no debug info. Probably there are problems in the Debug version of MFC DLLs.

For some configurations, the link fails and shows unresolved _security_cookie, I don't know how to solve it.

The 32-bits application can directly run (on WoW64). They said Visual Studio 2005 (beta) will do the job much easier. The developing environment for 64-bit application is amateur, therefore, I won't spend time in trying this again.


   

free6d1823 發表在 痞客邦 留言(0) 人氣()

台灣微軟於2005 年3月29日宣佈Visual Studio® 2005即將進入Beta 2版本,並強調Visual Studio® 2005將是微軟開發工具產品首次由軟體開發領域延伸至整個軟體開發生命週期(Software Life Cycle;SLC)的管理。Visual Studio® 2005內包含全新軟體開發生命週期管理工具Visual Studio® 2005 Team System,軟體開發人員只要利用Visual Studio 2005 Team System,便可在整個軟體開發生命週期中依照「架構設計人員」、「程式開發人員」及「軟體測試人員」等三種不同角色選擇適當的工具使用,並且共同運用Visual Studio® 2005 團隊開發伺服器平台協同作業,滿足企業客戶對軟體開發生命週期管理的需求。

微軟公司日前宣佈與美國卡內基美隆軟體工程學院 (Carnegie Mellon® Software Engineering Institute;SEI)合作,協助企業客戶在整個軟體開發生命週期上做更完善有效的管理。卡內基美隆軟體工程學院是由美國國防部所贊助,並由卡內基美隆大學負責營運管理,為世界首屈一指的系統工程和軟體工程整合模式研究機構,負責制定及推廣目前全球所廣為遵循的CMMI® (能力成熟度整合模式) 流程指導規範。卡內基美隆軟體工程學院的CMMI 流程指導規範,未來可望透過微軟解決方案架構 (Microsoft® Solutions Framework,MSF) 與Visual Studio® 2005 Team System的整合來具體落實。微軟解決方案架構(MSF)是一套充分整合的軟體開發流程、原則與實證成功經驗,具有高度延伸性、擴充性,將可以引導企業解決方案的軟體專案團隊,更快速地開展所有軟體開發流程,並遵循CMMI 所規範的標準。

透過 Visual Studio 2005 Team System,微軟解決方案架構(MSF)將提供兩個軟體開發流程範本:其一符合CMMI流程指導規範(MSF for CMMI Process Improvement),提供符合CMMI 規範標準的嚴謹團隊軟體開發程序。另一項是應用於靈活度很高的敏捷軟體開發程序(MSF for Agile Software Development),這是可強化反覆性軟體發展的功能的開發模式,適合一般企業軟體開發團隊使用。Visual Studio® 2005 Team System內建這兩種開發流程範本,協助企業客戶落實軟體開發標準,提高軟體開發過程的透明度與可預測性。

「Visual Studio 2005 Team System是與開發工具完全整合的軟體開發生命週期管理工具組。目前大多數的開發團隊必須採購好幾種不同的工具以滿足軟體開發的各種需求,而且不同工具之間往往難以互相溝通。微軟公司推出Visual Studio 2005 Team System的目的就是讓軟體開發流程中的所有相關人員,採用同一個工具組,遵循業界標準規範並有效分工,提高軟體開發生命週期的能見性與可追蹤性。現在將CMMI規範整合進來之後,除了軟體開發流程更加嚴謹之外,軟體開發的品質與時間也更能掌控。」台灣微軟公司開發工具暨平台推廣處產品行銷經理胡德民表示:「Visual Studio 2005 Team System是既有Visual Studio產品的延伸,且價格將比目前市場上的軟體生命週期產品更合理。台灣微軟公司希望能讓更多國內的企業與軟體業者迎頭趕上世界軟體開發標準化的趨勢,而不必受挫於高不可攀的導入成本,與疊床架屋的導入過程。」Visual Studio 2005 Team System的相關資訊,請至 http://www.msdn.microsoft.com 瀏覽。

free6d1823 發表在 痞客邦 留言(0) 人氣()

「UML之父」朗伯夫表示:軟體開發產業的發展變化迅速,台灣也必須加速「標準化」,才能跟國際接軌;擴大市場、爭取利潤!(何宏儒報導)

受邀來台的「UML之父」、IBM資深工程師朗伯夫(James Rumbaugh)認為:軟體開發產業已經從過去集中、地區化、穩定的發展型態;轉變成為既分散,又必須進行外部聯結;由於變化速度太快,站著不動絕對無法生存!他呼籲台灣加速軟體開發的「標準化」;強調:惟有跟國際接軌,才能擴大市場、爭取利潤!

經濟部次長施顏祥則表示:政府去年底啟動「製造」和「服務」的「雙引擎」經濟發展模式,後者又以「資訊服務」為重點;配合「Best旗艦計劃」,鼓勵資訊服務產業透過同業、異業分工整合,發展出整合性產品或服務旗艦。另外,政府也將持續推動「CMMI(能力成熟度整合模式)品質提升計劃」:目標2010年,能有百大廠商達到L3認證、3家達L5最高級認證。他表示:希望藉此提高台灣軟體產業的國際地位;並促進專業分工和策略聯盟。

free6d1823 發表在 痞客邦 留言(0) 人氣()

早上好,你們好嗎?很高興五年之後又來到中國,(五年前我來過中國)我看到在中國發生了很大的變化。我是從上海驅車趕往南京,一路上看到每隔幾百米就有一個新的建築拔地而起,我對中國發展的速度感到非常驚訝,希望在軟體行業能夠構建出同樣輝煌的建築。今天我要告訴大家一些有關軟體構建的秘密。

        今天我會告訴大家怎麼樣更加方便、容易地來開發軟體。為什麼大家都覺得軟體發展非常困難呢?我覺得主要原因是業務領域跟電腦領域之間的概念有很大的差別。一般來說業務是用自然的語言來表述,但是軟體有可能是用一些非常低級的電腦語言來表述的。構建一個軟體需要寫很多的代碼,要寫很多的控制邏輯,有很多複雜的東西在裏面。作為軟體發展者我們的任務就是要在業務跟軟體之間構建起一座橋樑。我們有四種方法使得軟體發展變得更加簡便。

         第一種方法就是儘量向業務領域描述靠近,儘量用高階語言來直接描述業務領域的概念。大家看到右面這張圖是用高階語言、抽象語言來描述的業務的概念,從業務模型到最終軟體的實現有可能還要構建一些中間的層次來搭建他們之間的橋樑。為了控制細節上的複雜度,就要很好地來構建我們軟體的架構,控制好構件之間的協作關係。為了減少我們書寫的代碼量,我們可能會使用一些自動化的工具來幫助我們自動生成代碼。大家都習慣於最簡單的軟體發展方式就是坐下來直接寫代碼,這看上去好像是一種最簡單的方式,但實際上最後會給我們帶來更大的麻煩。如果開發人員只是寫代碼而沒有設計的話,很有可能他所構建的這個系統的架構就不是那麼完善,同時代碼之間沒有很好地協調。不同的開發小組寫的代碼可能功能上會有所重疊或者是相互衝突,不同的開發小組就會使用不同的、不一致的格式進行交互。這是一種非常不好的協作模式,因為開發團隊之間會相互干擾,而破壞對方的一些工作成果。而且如果是開發人員去寫代碼的話,就意味著他們有更多的工作要去完成。在最糟糕的情況下大家看到這樣的系統有可能是非常脆弱的,任何改變都可能會破壞整個結構。

         我們向大家推薦的方法就是稱之為模型驅動架構這種新的方法(MDAModel Driven Architecture)。在這種方法裏我們使用一個高級的模型來描述一些業務領域的概念,基於這種高級的模型再來生成基於某種特定運行平臺的代碼。在這個過程中我們會使用一些自動化的工具,基於一些標準來生成我們的代碼。MDA方法是由物件管理組OMG (Object Management Group) 提出來的,OMG是國際化的標準化的組織。我們在開發的時候,起點是比較高級的業務領域的模型,這個模型我們稱之為平臺無關模型,也就是PIM (Platform Independent Model)。在這個平臺無關的模型裏我們著重關注的是業務的邏輯。涉及到具體平臺相關時我們會使用一種與實現相關的Profile,這種Profile描述了特定平臺的實現細節。基於平臺無關的模型以及特定平臺的Profile就可以自動生成基於某種特定運行平臺可運行的系統,稱之為平臺相關模型PSM (Platform Specific Model)。從同一種PIM出發,你可以針對多個不同的運行平臺來生成多個不同的PSM,最後基於PSM你還可以生成具體的代碼。在MDA裏我們需要三樣東西,首先我們需要來描述問題的模型,在這裏可以使用UML或者是使用新的領域描述語言DSL (Domain Specific Language) 來描述業務領域方面的模型;第二個需要利用架構框架來描述具體的實現,架構框架可以針對某種具體實現作出一些假設,從而基於這些假設來減少我們在建模階段所涉及的細節,最後通過一些自動化的工具來生成實際可運行的模型或者是模型的特定翻譯工具等等。

接下來我要介紹的是問題領域相關的模型。一種描述問題領域模型的方式就是使用UML,大家都知道UML最初是由Grady BoochIvar Jacobson和我共同創建的,後來OMG裏的其他成員也陸續對這個語言進行了擴展。現UML已經成為物件領域被全世界開發人員廣為使用的一種語言。跟編程語言相比UML是一種更加高級的描述語言,在這種語言裏我們減少了很多不必要的、細節的描述。理論上講UML可以應用於很多領域,我們可以對UML加以改造,利用一種稱之為UML Profile的機制可以使UML用於某些特定的領域。UML Profile是在UML的基礎上針對某些特定的領域進行一些改造,使得它能夠支持這些業務領域裏特定的業務概念。但即便是我們使用UML Profile這種特殊的機制,UML本身還是一種非常通用的語言,裏面還是包含了很多重複性的細節。另外一種方式就是利用稱之為領域描述語言的DSL語言來描述問題領域的這些概念。DSL是一種特殊的語言,有它自己的語法和語意,它是針對某一種業務領域而設計的。DSL是利用一些比較高級的概念來描述問題領域的概念,這樣它可以減少業務領域跟具體實現之間的差距。DSL裏也可以包括一些預先置好的資料與模式,基於DSL的模型可以減少一些重複性的控制邏輯的描述,同時生成更加底層、詳細的代碼。這裏我們來看一些現有的DSL的例子。

         首先大家想不到的是在30年以前我們就有這樣一種DSL語言,就yacc,在這個yacc裏用巴柯斯範式BNF來構建編譯器。yacc編譯器就可以利用你所描述的BNF來構建複雜的語法編譯工具,從而減少手工開發這種編譯工具的難度。另外一種大家想像不到的DSL是大家經常用的GUI編程工具,來幫助你搭建用戶介面。在這種工具裏就可以在螢幕上畫上你想要的表格、圖表或者是控制項等等。大家看到在螢幕上畫了這些控制項,在內部代表著上千行的代碼。但是開發人員不用去描述這些細節的控制邏輯,工具會幫你做到所有的這一切,這樣大大簡化了開發人員的工作量。另外一種DSL大家可能都想像不到,就是我們日常在使用的桌面編輯工具,像FrameMaker 或者是Word工具。作者可以很容易地用這個工具來寫下他們所編輯的書或者是插入一些他們想要的控制邏輯,像圖片等等。另外一種就是大家知道的MIDI,用於在樂器跟電腦之間的一種描述語言,它可以讓電腦也能夠產生音樂。音樂家利用MIDI這種語言不用編程就可以創造出音樂。另外一個例子就是數學上的一些應用工具,利用這些工具用戶可以直接用數學運算式、數學公式來描述一些複雜的概念。

         這裏我再給大家介紹另外一種特殊的DSL,就是以前大家廣為使用的SDLSDL是國際電信聯盟ITU所通過的一種標準,很多電信製造商都在利用這種標準來描述他們的電信設備,如交換機。很多知名的電信企業如摩托羅拉、愛立信等都在使用SDL來描述他們的應用。這種語言提供了複雜的描述手段,使得這些企業能夠利用它來描述電信上的一些複雜協議。我跟這些企業的開發人員都有過一些合作,我發現他們在使用一些工具時都存在著一些困難。因為隨著時代的進步SDL逐漸退出了主要的潮流,它並沒有包括一些最新的像UML工具裏的一些特性。最近物件管理組OMG剛剛完成一項專案,就是把UML升級到UML2.0。來自於摩托羅拉、愛立信的開發人員成為這個項目組的成員之一,在這個專案裏我們把SDL的一些概念也加入到UML2.0裏面。所以當UML2.0出來之後現在可以把SDL做成UML的一種Profile。這意味著傳統的SDL的用戶也可以利用UML工具來繼續你的軟體發展,同時也可以利用UML裏其他的一些特性。這也是一個很好的DSL語言的發展歷程,在這個歷程中大家看到如果一種概念型的領域描述語言比較有用的話,其實還會繼續延伸它的生命力,比如像SDL被加入到UML2.0裏去。

         有關這個領域描述語言有幾種不同的類型,有一種形式稱之為描述式 (Declarative) 的。在這種描述式的語言裏只需要描述我們需要做什麼,但是並不需要描述詳細的控制邏輯。這就像我們用數學公式來描述複雜的數學問題一樣,並沒有說明我們應該如何來解決這個問題。這種形式的DSL被廣為使用,因為簡化了開發的工作量,他們並不需要描述詳細的控制邏輯。如果電腦能夠自動地生成這種解決方案的話,這其實是一個非常有用的方式。但是實際的情況並不是如此,所以會有另外一種形式的DSL語言稱之為命令式(Imperative) 的,需要寫出一行行的指令來告訴如何解決這個問題。這種形式的DSL詳細描述了具體的控制邏輯,當然也給開發人員帶來了難度,因為它更難以使用。所以我們想出一種折中的方式把這兩種形式結合起來。在這種方式裏我們就用一些高級的描述性的方式來描述這些問題領域的概念。在開發的後期我們可以使用低級的命令行的方式來描述這些細化的控制邏輯。這種方式實際上是結合了前面兩種描述方式的優點。現在又有了一個非常流行的概念叫做觀點導向編程 (AOP – Aspect Oriented Programming) ,在這種方法裏我們是把不同的需要解決的問題劃分成不同功能的Aspect,一些有關Aspect的例子就包括如何控制安全性、如何永久地保存資料、如何提供一種併發的處理機制、以及如何記錄一些日常資訊等等。所以每一種Aspect實際上可以幫助我們來解決某一個特定領域的問題,但是這種解決方案是橫跨整個系統的。在這種方式裏我們需要有一個翻譯軟體把這些Aspect轉化成具體的代碼。解釋軟體應該知道Aspect之間的差異和相互的交互,應該能夠補充一些必要的代碼把他們整合起來。實際上從本質上講AOP方法跟剛才講的DSL語言是非常接近的,在每一種方法裏都有一種高級的描述方法來描述問題領域的這些概念,同時都需要有一種翻譯軟體把這個模型翻譯成最終的實現。現有的這些AOP語言並不是太好,有些並沒有我們想像中工作得那麼好。翻譯工具不能很好地工作,開發人員還是需要去描述一些他們之間實現的細節。我認為在AOP這種技術真正非常流行之前,我預期到AOP的下一個版本一定要增強轉換 (transform) 的功能,這樣才能能使得它更加流行。我認為這種DSL語言可以幫助我們來描述這種AOP 的自動生成、自動轉換功能。

  接下來我們來看一下架構框架。架構包括好幾樣東西,首先在構建架構時要做的是將系統分解成為一些子系統,這些子系統本身應該有完整的功能,同時應該能夠相互交互。子系統之間功能上不應該有重疊,在這種架構裏我們需要描述子系統之間交互的拓撲邏輯,常見的拓撲邏輯包括像流水線、星形結構等等。架構的另外一個方面就是要描述子系統之間的交互規則以及他們所交換的資料格式。另外架構設計師也需要描述有關資源管理的規則,這樣使得不同的開發人員能夠更加有效地來使用這些資源,這裏提到的資源就包括像記憶體、系統進程等等這些概念。所謂好的架構跟差的架構之間的差別就在於一個好的架構它能夠更好地適應系統將來的變化,注意這個變化是不會自動發生的,是應該由架構設計師為將來的變化做好準備。在一些好的架構裏會使用“鉤子(Hook)”這種機制,它可以使得我們不用修改這個系統就可以增加一些新的功能。我們經常看到很多專案延期的情況,原因就是專案裏的很多測試工作被忽略掉了。舉一個類比,大家想想現在汽車裏的發動機,發動機裏有很多感測器,這樣汽車上的電腦可以隨時感知發動機裏的工作狀態。大家想像一下如果先把發動機造出來再把感測器放進去,這實際上是行不通的,在設計發動機時就應該考慮要把感測器放進去。在做開發時架構設計師也要把測試這個概念加入到開發過程中去,使得測試成為我們開發過程的一部分。所以我們應該在早期設計架構的時候就應該考慮到測試,這樣能夠有效地提高軟體的品質。實際上大家都知道架構是很難去搭建的,我們想方設法使得架構這種工作對開發人員來說變得更加簡單。所以我們是把其他開發人員在開發過程中得到的一些好的架構經驗總結出來,稱之為架構框架。所謂的架構框架實際上是一種可重用的架構模式,這種模式是從好的架構模式裏總結出來,這些架構模式可以進一步地被其他人所重用。

         架構框架包括好幾樣東西,首先我指的是執行環境的框架,這裏包括很多小的元件,這些元件之間是相互繼承的。這些小的控制單元對用戶來講並沒有提供它的價值,它所關注的只是這些小的控制單元內部的控制邏輯。它也包括預先定義好的系統之間交互的介面、資料格式等等。所以我們可以預先構建好一個系統,逐漸地往裏面增加它的功能。實際上我們很難把所有的東西都組合在一起,一下子把它構成一個可運行的系統。如果你試圖把所有的東西一下子都集成起來的話,這實際上是非常困難的。一種比較簡單的方法就是你從一個小系統開始,在開發的過程中逐漸往這個系統裏增加功能,逐漸地把這個系統建立起來。基於這種開發理念,我們在設計架構框架的時候就會預留好一些擴展點,通過這些擴展點可以增加更多的功能,這些功能有可能體現為一些插件。在構造系統時就是把不同的插件插到不同的系統上去,好的架構框架應該也包括一些可重用的構件。開發人員應該利用現有的構件來開發系統,而不需要寫代碼。在構建一些複雜系統時,開發人員有可能也需要自己去開發一些構件,但是並不需要所有的構件都從頭做起。一切好的架構框架實際上都應該包括一些好的例子,這樣對我們可以有更大的幫助。實際上大家都有這種經驗,當你採用一種新技術時很難判斷怎麼樣把各種部件集成在一起,但是如果這時有一些很好的例子的話,我們的工作就會變得簡單。這裏大家看到的一些有關架構框架的例子就包括我們經常談到的Eclipse.NET或者是J2EE架構。

         使用架構框架可以給我們帶來很多好處,它可以使我們非常容易地利用DSL來描述一些現有的概念,也可以幫助我們來保證系統的一致性。如果系統是由很多小組來開發的話,這種框架可以在不同小組搭建的系統之間保持高度的一致性。另外它也可以保證基於同一種架構框架的不同開發應用也保持高度的一致性。另外它使得用戶的介面所使用的資料模式、用戶的體驗等等在不同的應用之間也保持高度的一致性。架構框架也可以很好地幫助增量式的開發,可以從一個小的系統開始,基於這種框架來逐步增加它的功能。另外架構框架也可以減少我們開發設計的工作量,使得不同的開發人員在設計的時候減少他們的分歧。

         我們有很多種方法來幫助我們描述一個架構框架,第一種方式是可以用UML模型來描述架構框架,可以描述結構模型、介面模型、描述模式等等。基於那種框架我們可以描述DSL語言的語法和語意。每一種架構框架都會包含一些具體的代碼,象C++或者是Java等等。每一個框架也應該包含一些文字描述來告訴使用者如何來使用這個框架。總而言之架構框架的基本思想是要從專家手裏把一些好的經驗總結出來,使得所有人都能夠共用這些好的經驗。一個類似的例子就是模式 (Pattern) ,模式已經是十年前的一個概念了。模式可以幫助我們來構建架構和解決一些具體的技術問題。什麼是模式呢?模式是針對常見問題提供的解決方案。很多模式都有不同的參數,這些參數使得模式可以應用於不同的領域。所謂的模式有很多種級別,有些是比較低級的,象通常我們講的設計模式,也有一些是幫助我們來構建模型的,也有一些是幫助我們來搭建系統架構的。跟我們剛才提到的架構框架一樣,每一個模式它都應該有這樣幾部分,包括架構、結構、內部的交互規則以及一些使用指南等等。另外一種共用經驗的方式就是來構建可重用的構件,構件是為一種特定的架構所設計的,在這個架構下不同的構件可以很好地相互合作。

          接下來我再給大家介紹的是MDA技術中有關自動化工具的部分。我們在做MDA開發時需要的是一個建模工具,這個建模工具可以幫助我們來描述模型以及各種模式。如果你開發的是一個小系統,只有兩三個人的小專案,就不需要建模工具。但是即便是簡單的問題也有必要來使用工具,例如你會使用計算器來把資料加在一起,這樣使你的工作更加簡便。對於一些大的專案、十幾個人的專案當然需要一個建模工具來幫助你們團隊協作、幫助你們來記錄你們設計的結果。假如沒有工具來協調大家工作的話,在建模過程中你們的工作有可能會相互重疊、相互衝突,有些資訊可能會丟失。工具同時也可以幫助我們來找出你設計中的一些錯誤或者是瓶頸之所在,幫助我們避免一些問題。一個好的自動化工具也可以根據你所指定的特定架構和平臺來生成可運行的代碼。自動化工具在生成代碼時也會生成一些追蹤資訊,就是從模型到代碼之間的關聯關係也會被記錄下來。對於一些大的專案而言,有可能你們會使用很多種不同的工具,這些工具有可能帶來的困難是他們之間很難進行資訊的交流。在這種情況下我們需要有一個公共的存儲庫來存放和管理所有的這些工具所產生的資料。這種公共的存儲庫應該可以使開發人員自由地修改資料,而並不影響其他人的結果。用於構建這種存儲庫的技術就包括MOFMeta-Object Facility元物件設施),另外一個是XML (eXtended Markup Language)

          用於MDA開發的另外一種工具主要是翻譯工具,可以幫助我們把模型自動地翻譯成為代碼。一個好的工具可以基於某種特定的平臺幫助我們生成代碼。另外一種翻譯工具就是一些代碼優化工具。一個例子是,大家可以把這種優化想像成為它可以把一個簡單的代碼映射成為複雜的代碼,從而提高運行效率。另外的轉化工具包括重新排版、組合這些代碼等等。實際上一個好的轉化工具是很難得到的,現在我們有很多種不同的變換工具,現在物件管理OMG正在進行的一個專案稱之為QVT (Query-View-Transformation) 項目,就是查詢、察看和變換,這個專案的主要目的是為變換工具制定一個標準。這個項目預定是在明年的第一季度結束,一旦這個標準出臺的話,它就可以使得不同的變換工具之間的協作變得更加簡單。

  對於這種變換工具我們到底有哪些要求呢?首先這種變換工具一定要理解源和目的語言的語法,同時在這種工具在生成代碼時,不要指望它生成的是最好的代碼(可能是比較好的代碼),因為通過這種工具已經減少了我們很大的工作量。實際上在這種變換工具上已經有很多年經驗的積累,比如大家經常用到的編譯器,我們希望把編譯器上好的經驗吸收過來。一方面需要構建自動化的變換工具來幫助我們轉換代碼,但是同時也要注意到我們現有的項目有很多歷史代碼。我們希望這種新的QVT標準能夠接受插件,以插件的方式來支援現有的這些代碼。對於這個變換工具的另外一個要求是要使得它能夠維護代碼跟模型之間的關聯,因為每當你對模型作出一個小的修改時,我們是希望這個工具能夠相應地生成變化的代碼,而不是每當你修改一部分模型之後這個工具需要把整個模型重新生成一遍,這是非常費時的。為了滿足這種要求,變換工具需要保持模型跟代碼之間的關聯關係。對於這種變換實際上我們有幾種不同的方式。第一種就是部分的轉換,在這種方式裏我們是把模型轉換為代碼,但是在這種轉換裏很多實現的細節是被忽略掉的。比如說現在大家正使用的很多UML工具實現的就是這種轉換,這種轉換只是幫你生成資料結構或者是一些簡單的代碼框架。所以這種變換方式生成代碼非常快,但是開發人員或者是編程人員需要做更多的工作來增加細節的描述。當然在這種變化裏存在風險:如果編程人員修改代碼的話,有可能會破壞掉代碼跟模型之間的關聯。我們稱之為雙向變換的技術實際上是可能的,只要我們在這種變換工具裏,在生成的代碼裏保持這種代碼跟模型之間的關聯關係就可以了。所以每當開發人員修改模型的話,我們就知道相應的哪一塊代碼需要做相應的修改了。但是這種逆向的變換往往是比較模糊的,從代碼到模型我們往往不知道怎麼樣根據代碼生成一個什麼樣的模型。主要的原因是因為代碼比模型包含的資訊更少,但是這種部分的變換技術其實是比較切實可行的技術,因為我們可以快速地利用它來建立我們的模型,並且生成我們的代碼。但是從長遠的角度來看這有可能並不是一個很好的解決方案。

 

          另外一種取而代之的方法是完全生成,在這種技術裏我們只有一種單向變換,就是從模型直接變換到代碼,而且是百分之百地生成代碼。在這種方法裏開發人員是不會去修改生成的代碼。但是這也對DSL語言提出要求,DSL應該有能力來描述足夠的細節。編譯器就是一種完全生成的很好例子。大家都有這種經驗,只會用編譯器生成代碼,但是從來不會去修改編譯器所生成的彙編代碼或者是資訊代碼。當我在很多年以前開發工作時這並不是一個事實,那個年代人們對編譯器還不是非常信任,開發人員經常去檢查編譯器所生成的代碼。現在編譯器已經發展得足夠成熟、足夠好了,所以大家都非常信任這種變換。現在大家用的另外一種完全生成的例子包括格式的轉換,比方現在有些工具可以幫助我們從UML模型生成XML格式。完全生成這種技術有可能適用於那些我們能夠掌控所有細節的場合下使用。儘管現在這種完全生成的技術不是非常成熟,但是我預期在將來這種技術應該是越來越可用的。

         第三種方式其實是把前面兩種方式都結合在一起,就是把代碼嵌入到模型中去。在這種方法裏開發人員會把代碼的片段插入到模型中去。在這種模型裏如果DSL的描述能力不夠的話,開發人員就會用編程語言來描述這些細節。當變換工具生成代碼時就會把開發人員插入的代碼嵌入到最後生成的代碼中去。所以如果開發人員想修改最終生成的代碼的話會修改這個模型中插入的代碼片段,重新利用這個模型來生成代碼。這種方式有可能更象我們談到的部分生成的例子,因為在這種技術裏開發人員還是需要來寫一些編程代碼。但是他們還是有不同的,因為在這種技術裏我們是把模型跟代碼存放在同一個檔裏。與其他的技術相比這種方式避免了我們丟失了模型跟代碼之間一致性的危險。因為這個變換工具知道插入的代碼在模型的什麼地方,所以它可以很好地在模型跟生成的代碼之間搭建這個映射。實際上這是一種非常靈活的技術,這種技術在幾十年以前,在剛才提到的編譯器的生成裏面就已經用到這種技術了。這是一種非常靈活的工作方式,但是它要求開發人員同時在兩個不同的層次進行工作,他既應該在高層次模型這個級別工作,同時也需要開發人員在低層次代碼這一級別進行開發工作。但是在當前這個情況下,在我們有更好的完全生成的解決方案之前,這有可能是一種比較實際的技術。最後是一種更加先進的變換技術,在這種變換技術裏我們為這種變換本身搭建起一個變換的模型。在這種技術裏面,我們會針對這種變換來建立起一個模型,並且利用這個模型把原模型跟目標代碼聯繫起來。利用這種開發技術進行開發的話,就意味著我們通常所講的設計就是要去構建出這樣一個變換。一旦我們搭建起這樣一個變換模型就可以把這種變換應用到很多源模型上去。比如說我們可以應用這種技術來構建一些模式,利用這個模式應用到很多領域上去。這是一種非常強大的技術,但是我並不認為這是每一個開發人員都適用的一種技術。這種技術需要一些特定的技能以及相關的知識。但我還是認為這種技術可以給大家帶來益處。誰可以用這種技術呢?是一些在開發團隊裏專門負責構建這個模式或者是構建架構框架的人,有一部分人可以用這種技術來構建出比較好的模式或者是架構框架,使得這種好的經驗可以使更多的開發人員受益。

 

          很多對於建模的批評就集中在模型是不可以運行的,我並不認為這是一種很好、很正確的想法。並不是說你看到一個模型就可以去執行它,實際上你可以利用一些自動化的工具來執行這個模型。早期的模型應該是不完整的,所以你不能期望它是可運行的。因為這個模型是不完整的,它裏面有可能缺少一些必要的資料或者是一些未知的決策,這些都會阻礙這個模型成為可運行的模型。在某些開發模型裏我們並不在意這種可運行,因為有些架構設計師他只關注於這種模式,但是並不在意具體的資料結構。這裏可以採用的一種技術就是儘早地對架構進行一些測試,有可能還有很多細節不清楚,但是我們還是有辦法對架構進行測試的,在IBM內部我們正在開發這種技術。也有人建議把UML變成一種可運行的語言,但是我認為這並不是一個很好的主意。基本的UML實際上是不可運行的,因為UML是一個作用非常廣泛的語言。UML在設計時就被設計成用來支持很多種不同的運行平臺、很多種不同的編程語言,所以如果想把UML變成可運行的跟你的想法之間就有一定的差距。另外UML本身作為一種建模語言,在其內部缺少了一些運行方面的語意,比如說你是不是需要多工,還是外部的資料交換的格式等等。怎麼樣使得UML變得可運行呢?你可以針對某一個特定的運行平臺來制定一個特定的UML Profile。比如說有一個現實的例子就是RealTime Profile,這個Profile使得UML可以在即時系統設計這個領域變得可運行。但是大家注意UML本身還是一個通用的描述語言,DSL可能是在很多情況下表述能力都要更強一些。我的想法是可以把UML作為DSL最終實現的過渡語言。我們可以把DSL所描述的語言模型轉換成為用UML描述的一個中間產品。然後可以用工具把這種中間化的UML模型進一步轉換成特定平臺上可以運行的代碼。這就等於是構建了從不同的DSL模型到最終可運行平臺的轉換跟變換。

剛才介紹了很多MDA的概念,下面做一下總結。MDA還是一種非常早期的技術,我預計要再過四到五年才可以看到MDA技術被廣泛地接受和採用。現在很多團隊還只是把MDA在一些小的試點專案裏應用,現在也有很多有關MDA技術的片斷,但是這些片斷其實並沒有在一起很好地協作。我建議大家如果有興趣的話還是要儘早地去嘗試這種技術,這樣可以更好、更早地來體會MDA給你帶來的好處。DSL這種語言還很少用到,但是會有更多的DSL語言出現。舉個例子,微軟最近也宣佈支持DSL,說明大家跟IBM都有同樣的想法。從這裏大家可以看到越來越多的企業在支援這些新的想法和概念。現在我們也有一些非常通用的框架存在,比如說剛才介紹的一些常用的像.NETJ2EE等。一些業界的標準化組織也在逐步地開發特定領域裏的框架模型。比如說OMG裏有一個專案正在開發針對醫療領域的框架模型,利用這種框架模型使得不同的醫療設備、診斷儀器之間可以很好地協作。現在也有一些團體在另外一些框架模型上工作,比如說針對金融行業、運輸行業的。為了更好地推廣應用MDA技術我們也需要有一個好的變換技術,當然這個變換技術現在還處於一個比較早期的階段。可以預見的是明年QVT技術可以成為現實,這就是一個很好的開端。但是在我們廣泛接受這種變換技術之前我想還是需要一段時間來適應、應用這種技術,一個更新版本之後這種技術才能得到更為廣泛的應用。我們也有很多經驗可以來自于現有的編譯器技術,可以把這些經驗加到變換技術裏去。現在看起來MDA技術還是一個非常新的技術,但是可以預見到它在將來的幾年裏會對整個軟體發展行業產生非常重大的影響。謝謝大家!

free6d1823 發表在 痞客邦 留言(0) 人氣()

在程式內用到一秒以下的計時通常可用 GetTickCount(), GetTickCount()傳回系統開機後到呼叫時已經過的毫秒(milliseconds). 但是經實驗結果, GetTickCount()的時間精度是 15mS, 亦即15毫秒以下的部份會四捨五入後再傳出來.

另外 C Run Time Library 亦提供一個 clock()函式 (定義在time.h), 其同樣傳回統開機後到呼叫時已經過的clock 數(1/CLOCKS_PER_SEC 秒, 在time.h內, CLOCKS_PER_SEC=1000). clock()的精度也是15 mS. 也就是說 GetTickCount()clock()其用法和傳回值其實是完全一樣.

若要使用精度較高的計時器, 可用QueryPerformanceFrequency()QueryPerformanceCounter().
先看其宣告:

BOOL QueryPerformanceFrequency(
LARGE_INTEGER
*lpFrequency // current frequency
);
BOOL QueryPerformanceCounter(
LARGE_INTEGER *lpPerformanceCount // counter value
);
QueryPerformanceFrequency取出系統高解析效能計數器之每秒振盪頻率, 
QueryPerformanceCounter
則取得開機後至目前之振盪周數. 注意其參數是64位元整數,運算時要
稍微注意.
例如,要計數某函式 myFunction()運算所花時間,可如下所示:
    LARGE_INTEGER StartTime, EndTime;
ULONGLONG frequency;
    QueryPerformanceFrequency((PLARGE_INTEGER)&frequency); 
QueryPerformanceCounter(&StartTime);
    myFunction();
    QueryPerformanceCounter(&EndTime);

    TRACE("運算 myFunction() 花費 %6.2f 毫秒.
",
        (double)((StartTime.QuadPart - EndTime.QuadPart)*1000)/
                 (double)frequency);

                                    

free6d1823 發表在 痞客邦 留言(1) 人氣()

  • Apr 13 Wed 2005 09:54
  • TRACE

MFC的TRACE具集指令, 可以在debug mode時啟用,而release mode時不執行. 但TRACE的參數是格式化的可變個數 (...). 到底MFC是如何做到的? 參考其定義檔 AFX.H

#ifdef _DEBUG

void AFX_CDECL AfxTrace(LPCTSTR lpszFormat, ...);
#define TRACE              ::AfxTrace

#else

inline void AFX_CDECL AfxTrace(LPCTSTR, ...) { }
#define TRACE              1 ? (void)0 : ::AfxTrace

#endif

假設在程式裡我們如下叫用
TRACE("Hello I am %d years old", nAge);

則 debug mode 等效於如下

::AfxTrace("Hello I am %d years old", nAge);

release mode 則如下

if(1==1)
  {}
else
  ::AfxTrace("Hello I am %d years old", nAge);

在release mode時會多做一個判斷式 if(1==1) (約3個組合語言碼) 但不會進入函式 ::AfxTrace()內, 當然還會佔用額外的程式碼空間. 不過與現在PC的資源比起來當然微不足道. 若要在release mode完全沒有Overhead, 可以用另外的巨集 TRACE0, TRACE1, TRACE2....
但需要視參數個數叫用不一樣的巨集.

若你不喜歡聯結MFC的library, 可以模仿以上的方式做自己的TRACE 巨集. 以下是我用的方法

mytrace.cpp

#ifdef _DEBUG
void MyDebugString(LPCTSTR lpszFormat, ...)
{
 char buffer[ 256];

 va_list argptr;
 va_start(argptr, lpszFormat);
 vsprintf(buffer, lpszFormat, argptr);
 va_end(argptr);
 ::OutputDebugString(buffer);
 
}
#endif

mytrace.h

#ifdef _DEBUG
void MyDebugString(LPCTSTR lpszFormat, ...);
#define TRACE MyDebugString
#else
inline void MyDebugString(LPCTSTR lpszFormat, ...){}
#define TRACE              1 ? (void)0 : ::MyDebugString
#endif

free6d1823 發表在 痞客邦 留言(0) 人氣()

 
使用new 配置記億體要用 delete 釋放; 使用 new []配置陣列, 就要用delete [] 釋放陣列. 如以下程式碼示範:
 
int *pi = new int; // allocates a single integer
int *pi_array = new int[10]; // allocates an array of 10 integers
delete pi;
pi = 0;
delete [] pi_array;
pi_array = 0;
 
不過, 事實上, 對int 等基本資料型別, new int[10] 直接被 VC compiler 編成 malloc (40), delete 與delete [] 一樣都編成 free(), 所以它們的結果是一樣而且不會出錯. 但若是一般的 class, new MyClass[10] 將會呼叫 MyClass 的constructor 10次且建立10份 MyClass的實體; delete [] pMyClass 會解構pMyClass 陣列內所指所有的實體(會呼叫10次destructor); 而 delete pMyClass 只會解構pMyClass 所指的實體, (只會呼叫1次destructor)而造成memory leak.
 
因此對於基本資料型別及結構(struct), delete 與delete[] 均OK. 但class則必須遵守 new 陣列就要 delete [].

free6d1823 發表在 痞客邦 留言(0) 人氣()

 
在驅動程式Kernel Mode 內中斷是如何運作的呢?
1.註冊中斷服務程式ISR
  在StartDevice()程序內呼叫 IoConnectInterrupt() API並在此API的引數指定你的ISR名稱   (如OnInterrupt()), 及ISR 傳入的個人資料. 這樣當硬體中段一發生.系統就會馬上呼叫   ISR.
  由於一呼叫完IoConnectInterrupt(),ISR馬上就起作用,因此建議呼叫前先關掉硬體中斷,  在結束StartDevice前再開啟硬體中斷即可.
2. ISR的內容
  由於ISR的中段要求層級IRQL是滿蠻高的(DIRQL), 因此在ISR做的事越少越好以免影響系統效能.  而且只能存取non-paged記憶體及呼叫有限的API.
  因為不同的硬體可以共用相同的中斷號碼, 而且系統不會判斷中斷是由哪個元件發出的.  系統只會將有曾經用IoConnectInterrupt()註冊過該中斷號碼的ISR一個個回呼.   因此驅動程式必須自行判斷是否是由自己的device發出的中斷, 若不是則馬上回傳false讓系統趕快再呼叫下一個ISR.
  因此ISR的程式流程大概是:
  1) 判斷是否是由自己的device發出的中斷, 若不是則馬上回傳false
  2) 做簡單處理,如清除元件的中斷狀態以便讓下一個中斷可以發出.
     ISR的傳入引數應提供足夠的資料結構讓ISR能儘快地完成要做的工作.
  3) 把複雜的工作交給DPC去做.
     呼叫IoRequestDpc()請系統在IRQL降到DISPACH層級時再呼叫驅動程式的DPC程序.
  4) 傳回true
3. DPC (Deffered Procedure Call)延遲呼叫程序
  顧名思義, DPC是延遲做一些較不迫切的工作. 但它的IRQL是DISPACH層級比一般程序的PASSIVE層級還高一層, 因此還是可中斷一般的程序, 但會讓給(deffer)DIRQL的硬體中斷.
  每個DeviceObject都會有一個附屬的DPC物件.因此在AddDevice()程序內就可以呼叫 IoInitializeDpcRequest() 來初始化DPC, 包括註冊DPC的處理程序及傳入引數.
4. ISR 與DPC如何分工?
  並沒有嚴格限制哪些要在ISR做,哪些要在DPC做. 以不影響系統效能為最大考量.

free6d1823 發表在 痞客邦 留言(0) 人氣()

看到網路上還有人在用MMX 做 memory copy, 因此不得不把之前實驗的結果公開,以免大家繼續被誤導.浪費時間又降低可攜性.
究境32bit, 64-bit, 128-bit 的搬移指令差異如何?請看以下實驗.
 
Compare three MemCpy implementation
 
1. C-Run Time memcpy()
2. MMS 64bit MOVQ
3. SSE2 128bits MOVAPS
 
Copy 614400 bytes from buffer A to buffer B. Test 8 times
 
The results (uS)
==#1  = #2  = #3 =#4  = #5 = #6 =#7  =#8
1. 549, 545, 522, 511,  548,  556, 610,  619
2. 677, 624, 547, 539,  542,  550, 532,  548
3. 529, 533, 551, 619,  619,  618, 569,  517
 
Note: test sequence
#1,#2: 2(MMX)first->3(SSE2)->1(C)
#3,#4: 3(SSE2) -> 1(C) -> 2(MMX)
#5,#6: 3(SSE2)->2(MMX)->1(C)
#7,#8: 1(C)->3(SSE2) ->2(MMX)
 
結論:
1. 三種方法效能其實差異不大. 先測試的方法花比較多時間,可能與memory catch有關.
   就資料的搬移,瓶頸應在memory的access時間, CPU內部應也是以最大頻寬將資料搬入, 因此MMX或SSE2完全佔不到便宜.
  MMX或SSE2只能在重算術運算時才有幫助吧.

free6d1823 發表在 痞客邦 留言(0) 人氣()