VB开发DLL
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
在动态链接技术中,模块和程序是分离的,模块独立于程序而存在于另一个分离的dll 文件中,这个dll文件是动态链接到程序中的。
那如何在vb中编写一个DLL程序呢?
首先,新建一个工程,然后先中“ActiveX Dll”工程。
然后开始编辑,往程序中添加你需要的部件和控件。
编辑完成后,保存工程,工程一般是以“.vbp”文件保存,定义的类以“.cls”和“.vbw”文件保存,窗体以“.frm”文件保存,添加的模块一“.bas”文件保存……。
接着选择“文件”菜单,弹出下拉框,选中“生成.dll”选项,它就会在上面弹出一个进度条“正在生成.dll文件”。生成以后是一个有好象齿轮状的图标。
当你需要在其他的程序中调用这个dll的时候,需要在系统中注册一下,具体的过程是开始->运行->打开”C:\WINDOWS\system32\regsvr32.exe”,然后找到你要注册的控件的路径,添加在regsvr32.exe的后面。
如果你要引用,就开一个“标准EXE”工程,然后在“工程”选项中,单击“引用”,找到你刚才的“.dll”的文件名,在前面的复选框中打勾,就可以引用你刚才在那里面写的方法等。
Public Function DllMain(
hinstDLL As Long, // long类型包含dll的instance handle 句柄. 也是dll的模块句柄fdwReason As Long, // 常数标识,入口点为何被调用
lpwReserved As Long //long类型提供关于DLL_PROCESS_ATTACH(DETACH)的信息
) As Boolean
fdwReason通常的取值
DLL_PROCESS_ATTACH (1)
进程装载了dll,每进程初始化要执行。A process is loading the DLL. Any per-process initialization should be performed.
DLL_THREAD_ATTACH (2)
进程交换(注入)一个新的线程,每线程初始化要执行。The process is spawning a new thread. Any per-thread initialization should be performed.
DLL_THREAD_DETACH (3)
一个线程结束。每线程清除要执行。A thread is exiting. Any per-thread cleanup should be performed.
DLL_PROCESS_DETACH (0)
一个进程断开dll链接,或者进程结束,每进程清除要执行。A process is detaching the DLL, or the process is exiting. Any per-process cleanup should be performed.
lpvReserved
一个long类型提供更多关于DLL_PROCESS_ATTACH 和DLL_PROCESS_DETACH的信息. (如果fdwReason是DLL_THREAD_ATTACH or DLL_THREAD_DETACH,则该参数无用) 如果fdwReason 是DLL_PROCESS_ATTACH, lpvReserved值无意义对于用函数LoadLibrary and GetProcAddress装载dll, 如果fdwReason 是DLL_PROCESS_DETACH, lpvReserved值无意义,如果返回值是从Win32 FreeLibrary function, lpvReserved值也无意义,如果进程结束调用入口点.
函数的返回值只有在fdwReason 是DLL_PROCESS_ATTACH才有意义,如果初始化成功,函数返回true,否则返回false.因为这个函数是window调用的入口点.传入这个函数的参数值是由windows决定.当一个线程被用win32 TerminateThread 函数和Win32 TerminateProcess 函数结束,没有调用入口点.
要开发一个windows dll,我们创建一个简单的数学函数库,下面代码存在一个.bas模块中名字:MathLib.bas
Option Explicit
Public Const DLL_PROCESS_DETACH = 0
Public Const DLL_PROCESS_ATTACH = 1
Public Const DLL_THREAD_ATTACH = 2
Public Const DLL_THREAD_DETACH = 3
Public Function DllMain(hInst As Long, fdwReason As Long,
lpvReserved As Long) As Boolean
Select Case fdwReason
Case DLL_PROCESS_DETACH
' No per-process cleanup needed
Case DLL_PROCESS_ATTACH
DllMain = True
Case DLL_THREAD_ATTACH
' No per-thread initialization needed
Case DLL_THREAD_DETACH
' No per-thread cleanup needed
End Select
End Function
开头包含一个DllMain过程,没有每进程或者每线程初始化需要执行。如果fdwReason 参数是DLL_PROCESS_ATTACH被调用,DllMain简单的返回True。另外,注意dll的函数中的输入参数和返回值用win32 api类型,不要用variant。
我们同样需要一个测试程序(test)验证我们的windows dll是否运行正常,所以创建个标准exe工程,由一个窗口和一个模块组成,模块代码就是declare声明。
Public Declare Function Incement Lib "MathLib.dll" (var As Integer) As Integer
Public Declare Function Square Lib "MathLib.dll" (var As Long) As Long
如果不在系统路径,最好加上dll全路径。
那么dll文件时怎么生成的呢?当我们选择文件->编译XXX.dll菜单选项来编译ActiveX dll,vb把我们的代码无缝结合成ActiveX dll,但是当我们检查vb的安装目录,其实这个过程并不是无缝的。在vb安装目录除vb6.exe,还有C2.exe和link.exe,一个是编译器,一个是链接器,这里就说明vb6.exe本身不能生成dll文件,而dll是由这2个程序一起运行生成的。
VB编译文件实际上采取了两次编译的方法,首先是调用C2.exe产生*.OBJ文件,然后调用Link.EXE连接。如果在LINK的时候添加EXPORT选项,实际上是可以输出函数的。但是,在VB的工程选项中将这些屏蔽了。我们可以通过改名C2.exe和link.exe来中断编译器和链接器的执行过程来发现vb是如何编译的。
下面的代码是个新版本的C2.exe调用真正的C2.exe编译器,其代码如下:
Public Sub Main()
On Error Resume Next
Dim strCmd As String, strPath As String
Dim oFS As New Scripting.FileSystemObject
Dim ts As TextStream
strCmd = Command