这可是本人的第一篇文章呀,原创的,请一定给予鼓励呀!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[file.GetLength()+1];
*(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