在VC下把exe文件转换成DLL文件
说到这里的方法,我们不得不说一下VC是里面生成的各个文件的作用:
.dsp 工程文件,文本格式,不可丢失或损坏
.dsw 工作区文件,丢失或损坏时,可点击.dsp文件打开工程,.dsw文件自动重建
.clw ClassWizard信息文件,ini格式,ClassWizard出问题时可删除它再重建
.map 映像信息文件,编制DLL写.def文件时,若不知道函数导出顺序,可在Prject/Settings/Link页中选中“Generate mapfile”,重新build,用记事本或其它类似程序打开生成的.map文件,里面可看到函数导出表.i在命令行环境下输入:cl ***.cpp /P (注意后面的参数P大小写敏感),程序文件夹中会生成.i文件,用记事本或其它类似程序打开,可看到.cpp 文件经预处理后的结果 .ncb 无编译浏览文件,当自动完成功能(自动显示成员变量列表)出问题时, 可删除它,build 后自动重建。
其它:
.aps 资源辅助文件,二进制格式
.opt 开发环境参数(如工具条位置)文件
.plg 编译信息(如error和warning信息)文件,html格式
.pch 预编译文件,可加快编译速度,但改文件非常大
.pdb 记录程序相关的数据和调试信息
.exp dll信息文件,编译dll时才会生成
.bsc 用于浏览项目信息,可在
Prject / Settings / Link 页中勾掉“Generate Browse Info File”,
禁止生成.bsc文件,以加快编译速度。但若使用Source Browser的话
就必须有这个文件
说到这里其它今天对我们有用的也就是*.dsp文件,它里面存放的是工程的一些配置信息。所以为了实现今天我们今天的目的,我们就要来改变*.dsp里面的配置信息,这样就可以把一个.exe文件转换成我们需要的dll文件。
好了,下面我们就开始动手吧:
1> 我们创建三个VC工程。命名分别为:DemoDll(Dialog类生成的.exe,用来把它转换成我们想要的DLL文件)DLL(默认的MFC DLL),CallDall(Dialog类用来调用我们转换成的Dll文件)
2> 分别打开DemoDll.dsp Dll.dsp文件
DemoDll.dsp
# Microsoft Developer Studio Project File - Name="DemoDll" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Application" 0x0101
CFG=DemoDll - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "DemoDll.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "DemoDll.mak" CFG="DemoDll - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "DemoDll - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "DemoDll - Win32 Debug" (based on "Win32 (x86) Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "DemoDll - Win32 Release"
# PROP BASE Use_MFC 6
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 6
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"stdafx.h" /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x804 /d "NDEBUG" /d "_AFXDLL"
# ADD RSC /l 0x804 /d "NDEBUG" /d "_AFXDLL"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 /nologo /subsystem:windows /machine:I386
# ADD LINK32 /nologo /subsystem:windows /machine:I386
!ELSEIF "$(CFG)" == "DemoDll - Win32 Debug"
# PROP BASE Use_MFC 6
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 6
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D"_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x804 /d "_DEBUG" /d "_AFXDLL"
# ADD RSC /l 0x804 /d "_DEBUG" /d "_AFXDLL"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
# ADD LINK32 /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "DemoDll - Win32 Release"
# Name "DemoDll - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=./DemoDll.cpp
# End Source File
# Begin Source File
SOURCE=./DemoDll.rc
# End Source File
# Begin Source File
SOURCE=./DemoDllDlg.cpp
# End Source File
# Begin Source File
SOURCE=./StdAfx.cpp
# ADD CPP /Yc"stdafx.h"
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=./DemoDll.h
# End Source File
# Begin Source File
SOURCE=./DemoDllDlg.h
# End Source File
# Begin Source File
SOURCE=./Resource.h
# End Source File
# Begin Source File
SOURCE=./StdAfx.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# Begin Source File
SOURCE=./res/DemoDll.ico
# End Source File
# Begin Source File
SOURCE=./res/DemoDll.rc2
# End Source File
# End Group
# Begin Source File
SOURCE=./ReadMe.txt
# End Source File
# End Target
# End Project
DLL.dsp
# Microsoft Developer Studio Project File - Name="Dll" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=Dll - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "Dll.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "Dll.mak" CFG="Dll - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "Dll - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "Dll - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "Dll - Win32 Release"
# PROP BASE Use_MFC 6
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 6
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WINDLL" /D "_AFXDLL" /Yu"stdafx.h" /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS"/D "_WINDLL" /D "_AFXDLL" /D "_MBCS" /D "_USRDLL" /Yu"stdafx.h" /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x804 /d "NDEBUG" /d "_AFXDLL"
# ADD RSC /l 0x804 /d "NDEBUG" /d "_AFXDLL"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 /nologo /subsystem:windows /dll /machine:I386
# ADD LINK32 /nologo /subsystem:windows /dll /machine:I386
!ELSEIF "$(CFG)" == "Dll - Win32 Debug"
# PROP BASE Use_MFC 6
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 6
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG"/D "_WINDOWS" /D "_WINDLL" /D "_AFXDLL" /Yu"stdafx.h" /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D"_WINDOWS" /D "_WINDLL" /D "_AFXDLL" /D "_MBCS" /D "_USRDLL"/Yu"stdafx.h" /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x804 /d "_DEBUG" /d "_AFXDLL"
# ADD RSC /l 0x804 /d "_DEBUG" /d "_AFXDLL"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "Dll - Win32 Release"
# Name "Dll - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=./Dll.cpp
# End Source File
# Begin Source File
SOURCE=./Dll.def
# End Source File
# Begin Source File
SOURCE=./Dll.rc
# End Source File
# Begin Source File
SOURCE=./StdAfx.cpp
# ADD CPP /Yc"stdafx.h"
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=./Dll.h
# End Source File
# Begin Source File
SOURCE=./Resource.h
# End Source File
# Begin Source File
SOURCE=./StdAfx.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# Begin Source File
SOURCE=./res/Dll.rc2
# End Source File
# End Group
# Begin Source File
SOURCE=./ReadMe.txt
# End Source File
# End Target
# End Project
好了,两个文件的不同点,我已经给大家标出来了,当然这里标出来的就只是我们需要修改的,所以真正的不同点不止这此。为了实现今天我们的功能这们只要修改上面我标出来的就可以了。
这就是我修改之后的DemoDll.dsp
(1) # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
(2) !MESSAGE "DemoDll - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
(3) !MESSAGE "DemoDll - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
(4) # ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WINDLL" /D "_AFXDLL" /Yu"stdafx.h" /FD /c
(5) # ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D"_WINDOWS" /D "_WINDLL" /D "_AFXDLL" /D "_MBCS" /D "_USRDLL"/Yu"stdafx.h" /FD /c
(6) # ADD BASE LINK32 /nologo /subsystem:windows /dll /machine:I386
(7) # ADD LINK32 /nologo /subsystem:windows /dll /machine:I386
(8) # ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D"_DEBUG" /D "_WINDOWS" /D "_WINDLL" /D "_AFXDLL" /Yu"stdafx.h" /FD/GZ /c
(9) # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG"/D "_WINDOWS" /D "_WINDLL" /D "_AFXDLL" /D "_MBCS" /D "_USRDLL" /Yu"stdafx.h" /FD /GZ /c
(10) # ADD BASE LINK32 /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
(11) # ADD LINK32 /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
好的,就这些了,上面就是我修改之后的DemoDll.dsp文件的内容,总共需要修改的是13处,其实没也没有什么,只要大家好好的看清楚也就OK了。
好了,文件我们也就转换好了,就让我们来调用一下试试吧:
CallDll.exe:
void CCallDllDlg::OnOK()
{
// TODO: Add extra validation here
HINSTANCE hInstance;
hInstance=::LoadLibrary("..//DemoDll//DemoDll.dll");
if(!hInstance)
{
MessageBox("LoadLibrary is falied!");
return;
}
FreeLibrary(hInstance);
CDialog::OnOK();
}
具体执行效果我就不在这里贴出来了,大家在自己执行一下就可以看到执行效果。