2011年12月19日 星期一

如何在Native Visual C++ (MFC)中呼叫使用Managed C++(CLR)的.dll

首先介紹CLR & MFCdll差別

CLR(Managed C++)
CLR開發出來的Dll需安裝.NET Framework才能跑,好處是可以使用.NET Framework函式庫寫出的Dll也可在Visual Studio直接加入參考使用。

MFC(Native Visual C++ plain C++)
MFC 開發出來的Dll則可以不需安裝.NET Framework,因此無法使用.NET Framework的函式庫,寫出的Dll也無法直接加入參考使用,則要用C語言的動態或靜態載入方式。
補充:
CLI又稱共同語言規範,用來定義.NET程式怎樣運作,CLRCLI規範的實做

動作步驟:


  • 由於ManagedDll必須要註冊才能使用
    • 按開始,由程式集進入Microsoft Visual Studio Visual Studio 2010 Tools
    • 開啟Visual Studio 2010 命令提示
    •  輸入managed DLL 所在的資料夾位置
    •  輸入
      • RegAsm.exe XXX.dll /tlb:XXX.tlb /codebase  如圖↓
  • 完成上面步驟則會產生.tlb
    • 補充:
      •  tlbCLR物件。因為tlb並不是C++標準的物件,必須編譯成標準的C++類型,使得C++開發者可以使用。 tlh表示(.h)  tli表示(.cpp)
      • 使用方法:
        • #import “XXX.tlb”,然後compiler,則會在debugrelease下面產生XXX.tliXXX.tlh物件。
  • 接著Native Visual C++必須支援CLR才可編譯。
  • 支援CLR流程:
    •  點擊Project,接者點擊 XXX Properties. (XXX 為你的專案名子)
    •  展開Configuration Properties,點擊 General.
    • 點擊 Common Language Runtime Support此欄框,選擇Old Syntax (/clr:oldSyntax),確定後按套用及確定。 如圖↓

  • 為了讓CLRBuild還必須加入一個reference (System.Windows.Forms)
    • 點擊Project,接者點擊 XXX Properties. (XXX 為你的專案名子)
    • 展開Comom Properties,點擊 Framework and References
    •  點擊Add New Reference,接著點擊Browse,加入System.Windows.Forms
    • System.Windows.Forms通常路徑為: C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Windows.Forms.dll
  • 完成此步驟後 ,接者在您的程式中加入#import指令並compiler 
  • #import "XXX.tlb" no_namespace, raw_interfaces_only
  • 之後會產生出的.tlh會在專案的debugrelease資料夾中。
  • 最後,在您的專案中加入#using <XXX.dll>  using namespace YYY; (YYYdllnamespace名稱),則可使用dll中的Device function寫入控制動作
  • 或是呼叫dll中直接設定參數的function,寫法如下: 
    • #include "stdafx.h"
      #include "tchar.h"
      // Import the type library.
       
      #import "..\ManagedDLL\bin\Debug\ManagedDLL.tlb" raw_interfaces_only
       
      //ManagedDLL為你dllnamespace的名稱
      using namespace ManagedDLL; 
      
      
      int _tmain(int argc, _TCHAR* argv[])
      {
          // Initialize COM.
          HRESULT hr = CoInitialize(NULL);
       
          // Create the interface pointer.
         //ManagedClass為你dllclass的名稱
          ICalculatorPtr pICalc(__uuidof(ManagedClass));
          
          long lResult = 0;
       
          //呼叫dll中的Add function
          pICalc->Add(5, 10, &lResult);
       
          wprintf(L"The result is %d\n", lResult);
       
          // Uninitialize COM.
          CoUninitialize();
          return 0;
      }
注意: 支援CLR會與OpenCV發生衝突,因此必須關掉OpenCV
附註: dll是由project產生出來的,所以必須要有它的原始碼,才會曉得如何使用它的function
想要更加了解可參考這網站:

2011年12月7日 星期三

免費好用的記憶體虛擬磁碟工具RAMDisk來幫你加速電腦

 

[新手教室]讓免費好用的記憶體虛擬磁碟工具RAMDisk來幫你加速電腦!(含加速教學)

 你的電腦記憶體太多用不完,或是不知道怎麼利用嗎?沒關係,阿正老師介紹一套免費的軟體Dataram RAMDisk,幫你將RAM模擬成一台虛擬磁碟,可把一些常用軟體的快取目錄設定進去,加快電腦的反應速度、減少硬碟的I/O次數。RAMDisk的另 一個優點是幫你將虛擬磁碟的內容儲存在硬碟中,還可設定開機自動掛載,因此不必擔心裡面的內容一關機就不見囉! 想加快電腦速度的玩家們可別錯過了!....

2011年12月6日 星期二

執行外部程式 -- CreateProcess(),ShellExecuteEx()

要執行外部程式,ShellExecute() 與 WinExec() 都是較為簡單的方法,
但卻無法進一步掌握新的process的狀態
 
如果要進一步掌握新的process執行的狀態,可以呼叫 CreateProcess() 或 
ShellExecuteEx(),並透過 WaitForSingleObject 以等待新的process執行完後
,再繼續下一步驟,以控制程式同步
  • ShellExecuteEx() 的例子
 SHELLEXECUTEINFO   ShExecInfo   =   {0}; 
 ShExecInfo.cbSize   =   sizeof(SHELLEXECUTEINFO); 
 ShExecInfo.fMask   =   SEE_MASK_NOCLOSEPROCESS; 
 ShExecInfo.hwnd   =   NULL; 
 ShExecInfo.lpVerb   =   NULL; 
 ShExecInfo.lpFile   =    "c:\\MyProgram.exe ";                         
 ShExecInfo.lpParameters   =    " ";   //可以加參數          
 ShExecInfo.lpDirectory   =   NULL; 
 ShExecInfo.nShow   =   SW_SHOW; 
 ShExecInfo.hInstApp   =   NULL;             
 ShellExecuteEx(&ShExecInfo); 
 WaitForSingleObject(ShExecInfo.hProcess,INFINITE); 
  
  • CreateProcess()函數的例子:  
 PROCESS_INFORMATION   piProcInfo;    
 STARTUPINFO   siStartInfo; 
  
 //   Set   up   members   of   STARTUPINFO   structure. 
 siStartInfo.cb   =   sizeof(STARTUPINFO);    
 siStartInfo.lpReserved   =   NULL; 
 siStartInfo.lpReserved2   =   NULL;    
 siStartInfo.cbReserved2   =   0; 
 siStartInfo.lpDesktop   =   NULL;    
 siStartInfo.dwFlags   =   0; 
  
  
 //   Create   the   child   process. 
 CreateProcess( 
 NULL, 
 strCmdLine.c_str(), 
 NULL,   //   process   security   attributes 
 NULL,   //   primary   thread   security   attributes 
 0,   //   handles   are   inherited 
 0,   //   creation   flags 
 NULL,   //   use   parent 's   environment 
 NULL,   //   use   parent 's   current   directory 
 &siStartInfo,   //   STARTUPINFO   pointer 
 &piProcInfo);   //   receives   PROCESS_INFORMATION 
  
 //   Wait   for   the   processs   to   finish 
 DWORD   rc   =   WaitForSingleObject( 
    piProcInfo.hProcess,   //   process   handle 
    INFINITE);    
 
 
 

執行外部程式 -- ShellExecute

HINSTANCE ShellExecute(                                              
    HWND hwnd,    // handle to parent window                
    LPCTSTR lpOperation, // pointer to string that specifies operation to perform
    LPCTSTR lpFile,  // pointer to filename or folder name string
    LPCTSTR lpParameters, // pointer to string that specifies executable-file parameters
    LPCTSTR lpDirectory, // pointer to string that specifies default directory
    INT nShowCmd   // whether file is shown when opened          
   ); 
 
其中hwnd是主要執行該程式的視窗,通常就是我們自己的程式視窗。不過也可以給NULL,表示沒有特定的視窗。 lpOperation是您要執行的動 作,這個動作有三個:
  • open -- open的方式是讓系統自己依據檔案的型態來決定以何種方式開啟它。舉例來說,如果lpFile是一個可執行檔,那麼這個檔案就會 被執行。如果他是一個文件檔,則會被對應的軟體所開啟。如果開啟的是一個目錄,自然就是用Explorer來開啟囉。
  • print -- print很明顯的就是將檔案送到 printer queue裡面去列印。
  • explorer -- 原則上只能用在目錄,是用來開啟目錄用的。
lpFile正如前面所說就是一個表示要開啟的檔案。而lpParameters主要用於lpFile所指向的是一個可執行檔時,用這個參數將執行 檔所需 的參數傳給它。而lpDirectory是進行開啟動作時的預設路徑,如果是NULL,表示為預設路徑。 最後一個nShowCmd主要表示該檔案開啟時的行為,主要有下面幾個值可用:
  • SW_HIDE 執行檔案時,將視窗隱藏起來。.
  • SW_MAXIMIZE 將視窗最大化執行
  • SW_MINIMIZE 將視窗最小化執行
  • SW_RESTORE 若視窗執行時是最小化,透過此參數,可將其回復原來大小顯示。
  • SW_SHOW 以視窗預設大小顯示,並且設為主動視窗
  • SW_SHOWDEFAULT 同SW_SHOW
  • SW_SHOWMAXIMIZED 執行時將視窗最大化,並且設定為主動視窗。
  • SW_SHOWMINIMIZED 執行時將視窗最小化,並且設定為主動視窗。
  • SW_SHOWMINNOACTIVE 執行時將視窗最小化,並且不會變動現行的主動視窗。
  • SW_SHOWNA 執行時並不會變動現行的主動視窗。
  • SW_SHOWNOACTIVATE 同SW_SHOWNA。
  • SW_SHOWNORMAL 當程式執行時,若為最大化或最小化,將會回復到原來的大小,並且設定為主動視窗。
下面幾個例子介紹幾個常見的用法:
// 開啟某個目錄: ShellExecute(NULL, "open", "c:nwindows", NULL, NULL, 0);

// 開啟某個程式: ShellExecute(NULL, "open", "c:nwindowsnnotepad.exe", "c:xxx.txt", NULL, SW_SHOWNORMAL);

// 列印某份文件: ShellExecute(NULL, "print", "c:nxxx.doc", NULL, NULL, 0);

// 開啟某個網頁: ShellExecute(NULL, "open", "https://www.google.com/", NULL, NULL, 0);
 
 
Ref. 
http://msdn.microsoft.com/en-us/library/windows/desktop/bb762153%28v=vs.85%29.aspx
http://www.dev.idv.tw/mediawiki/index.php/ShellExecute%E7%9A%84%E7%94%A8%E6%B3%95
http://www.xspace.idv.tw/bo_blog/read.php?168

2011年12月1日 星期四

Winsock 2 Network Programming

Tutorials on 'Advanced' Winsock 2 Network Programming

http://www.winsocketdotnetworkprogramming.com/winsock2programming/

Chapter 5 Winsock 2 I/O Methods

http://www.winsocketdotnetworkprogramming.com/winsock2programming/winsock2advancediomethod5chap.html

2011年7月5日 星期二

OpenCV 2.3

這個檔案已經build 好 vs2010 (vc10), vs2008 (vc9) , 32bits, 64bits 都有
下載後解壓到C:\
留下自己要用的版本,其他都可以砍掉,這樣比較節省空間
為了跟其他library 搭配使用,建議還是寫 32bits 就好
哪些資料夾該砍掉?
C:\OpenCV2.3\opencv 留著,裡面是source code 跟 sample
C:\OpenCV2.3\build 裡面, bin , include 都留
C:\OpenCV2.3\build\x64 可以砍掉
C:\OpenCV2.3\build\x86 只留 vc10 (使用vs 2010)
2.3 跟 2.2 的路徑不大一樣, 所以vs 2010 那邊,把路徑重設應該就可以用了
如果遇到 "應用程式無法正確啟動", 建議自行build, 應該就可以解決了

2011年6月17日 星期五

視窗程式設計

上課時間預計7/13 下午2點開始, ...
請先至70808 問學長上課地點


目前要參加的有
計榮群
張凱棋
林哲緯
麥紘嘉
劉冠毅
許致豪
李易學