這可是本人的第一篇文章呀,原創的,請一定給予鼓勵呀!2009-12-24-16:54:23
DOS環境下利用Borland C++產生dll及dll工程
在實際的應用中,我們往往需要編寫適合自己的能夠實現編譯功能的文字編輯器,要設計一個編譯器,似乎是不可能的。比較通常的做法是自己編寫介面,然後借用現有的編譯器來完成編譯調試功能。但是網上對這一方面的介紹少之又少,本人也是在走投無路下,經過多次的測試實驗才得到了一種比較簡單的做法,來滿足自己的需要。今把它寫出來,權且當作是在拋磚引玉,望高手們不要取笑,並多加指導,若有其他更為有效做法,請勿必指教。
圖一是我用VC設計了一個文字編輯器。在文本編輯框中輸入DLL文字檔,點擊工具列按鈕 ,則在指定路徑下產生.dll檔案,以及在右下框中輸出編譯資訊。點擊 按鈕,則自動產生DLL工程,並運行載入此工程,從而利用Borland C++6.0軟體完成對DLL檔案的調試。
圖一
要完成上述功能就要解決兩個問題,一是如何在VC設計中利用Borland C++工具產生.dll檔案。二是如何產生DLL工程檔案。查看了Borland C++安裝目錄/bin/發現其中有兩個工具可供我們直接利用,bcc32.exe,ilink32.exe。利用VC對DOS命令列的處理可以較容易的解決了產生DLL檔案的問題。VC對DOS命令列的處理可以簡單的使用WinExec命令。雖然Microsoft認為WinExec已淘汰,但是在許多時候,簡單的WinExec函數仍是運行新程式的最好方式。
為驗證方法的正確性,我編寫了一個簡單的測試程式,二,程式見原代碼。首先,選擇你要儲存產生DLL檔案的路徑,再輸入DLL的C檔案。點擊“建立C檔案”,則在你所指定的目錄下產生一個.C檔案,並使能後面兩個按鈕,再點擊“產生DLL檔案”則產生DLL檔案,點擊“產生DLL工程”則產生DLL工程,下面我將一一解釋如何產生DLL檔案和DLL工程。
圖二
一、Dos下利用Borland C++工具產生.dll檔案:
①基本思路:在DOS下先利用bcc32.exe工具,編譯產生.obj檔案,再利用ilink32.exe產生.dll檔案。
②產生.obj檔案Dos文法:bcc32 –c “要編譯C檔案路徑”。
查看更多協助可在DOS下輸入bcc32 –h,斷行符號。註:-c --只產生.obj而不連結,-I --包含的標頭檔。各路徑中若存在空格則路徑要用“”包含。
③產生.dll檔案Dos文法:ilink32 /Tpd “待連結的obj路徑” “ ,要產生的dll路徑”。
查看更多協助可在DOS下輸入ilink32 斷行符號。註:dll路徑前的‘,’前一定要有一個空格。各路徑中若存在空格則路徑要用“”包含。
部分代碼:
//按鈕“產生DLL檔案”訊息響應函數
void CCreateDLLDlg::OnBtnDllfile()
{
CString strDos; //DOS命令列
CString strCFilePath; //DLL的C檔案的全路徑
CString strObjPath; //產生的OBJ檔案的全路徑
CString strDllPath; //產生的DLL檔案的全路徑
strCFilePath = m_strPath+"//Untitled.c";
strObjPath = m_strPath+"//Untitled.obj";
strDllPath = m_strPath+"//Untitled.dll";
strDos = "c://windows//system32//cmd.exe /c ";
strDos += "bcc32";
strDos += " -c "; //-c只產生OBJ,而不LINKER,要有空格
strDos += "/""; //路徑中有空格就一定要在路徑中加上“”
strDos += strCFilePath;
strDos += "/"";
SetCurrentDirectory(m_strPath); //設定當前DOS的執行路徑
WinExec(strDos,SW_HIDE); //產生OBJ
strDos = "c://windows//system32//cmd.exe /c ";
strDos += "ilink32 /Tpd ";
strDos += "/"";
strDos += strObjPath;
strDos += "/"";
strDos += " ,";
strDos += "/"";
strDos += strDllPath;
strDos += "/"";
WinExec(strDos,SW_HIDE); //從指定的OBJ檔案連結產生DLL檔案
}
二、Dos下產生DLL工程檔案
步驟:
①手動用Borland C++建立一個DLL空工程,得到.bpr,.bpf檔案。例如:Project1.bpr,Project1.bpf其DLL的C檔案名稱為Unit1.cpp。
②用記事本或Word軟體開啟Project1.bpr檔案,將工程名Project1全部替換成一個複雜的字串,如@#$%TPSName@#$%,也將C檔案名稱替換成另一個字串如@#$%CFile@#$%,儲存。
③產生工程時用VC的API函數CopyFile()將.bpr,.bpf這兩個檔案複製到指定目錄下,並將其檔案名稱改成你所要產生工程的檔案名稱。同時在該目錄中還應有dll的C檔案。再讀取.bpr檔案將複雜的字串改回成你的工程名,C檔案名稱,路徑。這樣就完成了一個工程的建立。
④執行ShellExecute(this->m_hWnd,"open","bcb.exe",“建立工程的全路徑”,"",SW_SHOW );自動載入建立的工程。
部分代碼:
//產生DLL工程並載入
void CCreateDLLDlg::OnBtnDllproject()
{
// TODO: Add your control notification handler code here
CString buf;
CopyFile(m_strDirPath+"//Untitled.bpr",m_strPath+"//Untitled.bpr",0);//從工程目錄下複製檔案
CopyFile(m_strDirPath+"//Untitled.bpf",m_strPath+"//Untitled.bpf",0);
CFile file(_T(m_strPath+"//Untitled.bpr"),CFile::modeReadWrite);
char *pRead = new char;
*(pRead+file.GetLength()) = '/0'; //多分配一個位元組
file.Read(pRead,file.GetLength());
buf.Format("%s",pRead);
buf = pRead;
buf.Replace("@#$%TPSName@#$%","Untitled"); //可跟據具體需要改變,
//本程式為簡單起見工程名和檔案名稱都用Untitled
file.SetLength(0);
file.Write(buf,buf.GetLength()); //修改後寫迴文件
delete[] pRead;
file.Close();
CString strTest = "/"";
strTest += m_strPath;
strTest +="//Untitled.bpr";
strTest +="/"";
ShellExecute(this->m_hWnd,"open","bcb.exe",
strTest,"",SW_SHOW );
}
三、補充
由於bpr檔案版本的關係,本程式只能放在路徑中不含有空格的目錄下,DLL工程才能正常實行,要改進的話請自行更改代碼。本文只是提供一種方面,很多細節並未考慮完全,請一定見諒。如果你的DLL的C檔案有包含標頭檔的話,可以把產生.obj檔案Dos的文法多加一項“-I”,並在替換.bpr檔案裡還要替換檔案包含的路徑。具體見.bpr檔案。
有其他問題或有更好提議的話請與本人聯絡。
Email:zp_huang7@163.com