Tác giả: Sưu tầm
Cấp độ bài viết: Chưa đánh giá
Tóm tắt: Tạo một Standard DLL dùng VB6 - Dành cho các Fan của VB
Bác Peterdrew đã có bài viết về Cách tạo và sử dụng DLL trong VB rồi, nhưng bác ấy chỉ tạo được DLL dạng ActiveX (DLL có chứa các Class ở trong nó) bằng Vb6. Còn Standard DLL (DLL kiểu của windows, các hàm trong nó được khai báo bằng từ khoá Declare trong Vb6) thì bác ấy lại tạo bằng VC++. Nhưng khổ nỗi là em lại không rành VC++, em là tín đồ của VB mà. Vậy nếu muốn tạo Standard DLL kiểu như bác Peter tạo trong VC++ thì phải làm thế nào.
Sau đây là cách tạo Standard DLL trong VB6 em sưu tầm được, xin đưa lên đây để bác nào không rành VC++ mà vẫn muốn tạo Standard DLL (giống em) có thể tham khảo
1. Một số khái niệm:
- +DllMain: Là hàm khởi tạo (và cũng là hàm huỷ) trong DLL. Windows sẽ gọi hàm DllMain trong DLL mỗi khi DLL được sử dụng đến hoặc ngưng sử dụng. Vì vậy hàm DLLMain sẽ được sử dụng để khởi tạo và huỷ các biến cần thiết. DllMain có thể có hoặc không cũng được (tuỳ vào DLL mà bạn viết có cần khởi tạo và dọn dẹp hay không)
+Module Definition File: Là tệp tin mô tả các module ở trong file DLL. File DLL kiểu Standard khi viết ra có thể có nhiều hàm ở trong. Tệp mô tả sẽ chỉ ra thứ tự các hàm, nó tham gia vào quá trình biên dịch mã nguồn thành tệp DLL. Tệp mô tả có phần mở rộng là DEF
- A. File Link.exe đóng vai trò gì?
+ Trong IDE của Vb6, khi ta chọn Make chương trình của ta thành file DLL (kể cả khi ta make chương trình thành file EXE) thì IDE sẽ trước tiên gọi file C2.exe để dịch code của chúng ta thành các file *.OBJ. Sau đó nó gọi tiếp file Link.exe để liên kết các file *.OBJ lại tạo ra file DLL hoặc file EXE. Vậy file Link.exe đóng vai trò liên kết các file OBJ để tạo ra tệp dạng binary (Exe hoặc DLL) cuối cùng. Cả file C2.Exe và file Link.exe đều nằm trong C:\Program Files\Microsoft Visual Studio\VB98
B. Vì sao phải Mod lại file Link.exe?
+ Trong VB6, khi IDE gọi file Link.exe để liên kết các file *.OBJ lại, nó truyền cho file Link.exe một loạt các tham số như: đường dẫn của các file *.OBJ, kiểu file đích sẽ tạo ra (DLL hay EXE), đường dẫn của đích sẽ được tạo ra, và 1 số các tham số khác nữa. Tuy nhiên, trong rất nhiều tham số này, lại thiếu mất một tham số là "/DEF". Tham số /DEF chính là tham số chỉ ra đường dẫn của các tệp Module Definition (các tệp *.DEF) ở phần 1. Thiếu các tệp này, DLL tạo ra sẽ không thể sử dụng được các hàm Public bằng phương pháp Declare. Chính vì vậy, ta phải Mod lại file Link.exe để thêm tham số này vào lúc biên dịch
C. Mod lại file Link.exe như thế nào?
+ Phương pháp ở đây là tạo ra 1 file Link.exe giả đặt trong thư mục VB98, còn file Link.exe thật thì đổi tên thành 1 file khác (ví dụ là LinkThat.exe). Khi IDE gọi file Link.exe giả (do ta mod lại) thì file giả của chúng ta sẽ làm nhiệm vụ đọc các tham số được IDE truyền sang, thêm tham số /DEF vào và gọi file LinkThat.exe với tham số mới (đã có /DEF). Tất nhiên là phải kiểm tra, nếu có tồn tại các file *.DEF và project cần tạo là project kiểu DLL thì mới thêm tham số
+ Tiến hành Mod lại file Link.exe
- Mở Vb6, tạo 1 Project mới dạng EXE application
- Xoá Form1 mà Vb đã tự tạo ra cho ta, thêm vào 1 Module mới, đặt tên bất kỳ
- Add Reference vào tệp SCRRUN.DLL trong System32 để sử dụng được đối tượng FileSystemObject
- Copy đoạn code sau, Paste vào Module vừa thêm:
- Option Explicit
- Public Sub Main()
- Dim SpecialLink As Boolean, fCPL As Boolean, fResource As Boolean
- Dim intPos As Integer
- Dim strCmd As String
- Dim strPath As String
- Dim strFileContents As String
- Dim strDefFile As String, strResFile As String
- Dim oFS As New Scripting.FileSystemObject
- Dim fld As Folder
- Dim fil As File
- Dim ts As TextStream, tsDef As TextStream
- strCmd = Command
- 'Ghi Log vào file lnklog.txt mỗi khi chạy
- Set ts = oFS.CreateTextFile(App.Path & "\lnklog.txt")
- ts.WriteLine "Beginning execution at " & Date & " " & Time()
- ts.WriteBlankLines 1
- ts.WriteLine "Command line arguments to LINK call"
- ts.WriteBlankLines 1
- ts.WriteLine " " & strCmd
- ts.WriteBlankLines 2
- ' Kiểm tra xem các tệp .DEF hoặc tệp RES có tồn tại trong thư mục làm việc hay không
- '
- 'Lấy đường dẫn thư mục làm việc từ tệp .OBJ đầu tiên
- intPos = InStr(1, strCmd, ".OBJ", vbTextCompare)
- strPath = Mid(strCmd, 2, intPos + 2)
- intPos = InStrRev(strPath, "")
- strPath = Left(strPath, intPos - 1)
- 'Mở thư mục làm việc
- Set fld = oFS.GetFolder(strPath)
- 'Lấy các file trong thư mục làm việc
- For Each fil In fld.Files
- If UCase(oFS.GetExtensionName(fil)) = "DEF" Then
- strDefFile = fil
- SpecialLink = True
- End If
- If UCase(oFS.GetExtensionName(fil)) = "RES" Then
- strResFile = fil
- fResource = True
- End If
- If SpecialLink And fResource Then Exit For
- Next
- 'Thay đổi tham số gọi tệp Link, nếu có tồn tại file .DEF hoặc RES
- If SpecialLink Then
- ' Phần này để kiểm tra xem có phải file .DEF định nghĩa tệp DLL tạo ra
- ' sẽ trở thành Applet của Control Panel hay không. Phần này em chưa tạo
- ' bao giờ nên cũng chưa rõ lắm
- Set tsDef = oFS.OpenTextFile(strDefFile)
- strFileContents = tsDef.ReadAll
- If InStr(1, strFileContents, "CplApplet", vbTextCompare) > 0 Then
- fCPL = True
- End If
- ' Thêm tham số /DEF cùng với đừơng dẫn file .DEF vào trước tham số /DLL
- intPos = InStr(1, strCmd, "/DLL", vbTextCompare)
- If intPos > 0 Then
- strCmd = Left(strCmd, intPos - 1) & _
- " /DEF" & Chr(34) & strDefFile & Chr(34) & " " & _
- Mid(strCmd, intPos)
- End If
- ' Thêm các tệp Resource vào nếu có
- If fResource Then
- intPos = InStr(1, strCmd, "/ENTRY", vbTextCompare)
- strCmd = Left(strCmd, intPos - 1) & Chr(34) & strResFile & _
- Chr(34) & " " & Mid(strCmd, intPos)
- End If
- ' Nếu tệp định tạo là Applet của Control Pannel, đổi tên file đích từ .DLL thành .CPL
- If fCPL Then
- strCmd = Replace(strCmd, ".dll", ".cpl", 1, , vbTextCompare)
- End If
- ' Ghi Log các tham số sau khi sửa
- ts.WriteLine "Command line arguments after modification"
- ts.WriteBlankLines 1
- ts.WriteLine " " & strCmd
- ts.WriteBlankLines 2
- End If
- 'Gọi tệp LinkThat.exe với tham số đã sửa
- ts.WriteLine "Calling LINK.EXE linker"
- Shell "linkthat.exe " & strCmd
- If Err.Number <> 0 Then
- ts.WriteLine "Error in calling linker..."
- Err.Clear
- End If
- ts.WriteBlankLines 1
- ts.WriteLine "Returned from linker call"
- ts.Close
- End Sub
- Dịch chương trình trên thành file Link.exe
- Đổi tên file Link.exe của Vb6 (trong C:\Program Files\Microsoft Visual Studio\VB98) thành LinkThat.exe
- Copy file Link.exe vừa tạo được ở trên vào thư mục Vb98
- - Tạo 1 Project mới trong Vb6, kiểu Project là ActiveX DLL
- Để nguyên Class1 mà Vb6 đã tạo sẵn cho bạn. Không cần Code gì vào đó cả, nhưng vẫn phải giữ nó lại vì Vb6 cần phải có 1 Class trong Project kiểu ActiveX DLL thì nó mới chạy
- THêm 1 Module mới với tên tuỳ ý. Bạn có thể bắt đầu viết các hàm cho riêng mình vào Module này. Tôi đưa ra 1 ví dụ đơn giản với các hàm tính toán. Module của tôi có dạng như sau:
Trừ hàm DllMain, các hàm khác các bạn có thể thêm bớt tuỳ ý
- 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
- Public Function Add(ByVal a As Integer, ByVal b As Integer) As Integer
- Add = a + b
- End Function
- Public Function Subtract(ByVal a As Integer, ByVal b As Integer) As Integer
- SubTract = a - b
- End Function
- Public Function Square(ByVal a As Integer) As Integer
- Square = a * a
- End Function
4. Tạo tệp Module Definition File (.DEF)
- Dùng Notepad, soạn với nội dung sau:
Code: Select all
NAME TenTuyY
LIBRARY TenTuyY
DESCRIPTION "Mo ta cua tep DLL- gi cung duoc"
EXPORTS DllMain @1
Add @2
Subtract @3
Square @4
- - Phần nội dung sau NAME, LIBRARY, DESCRIPTION bạn có thể đặt tuỳ ý
- Theo sau EXPORTS là tên các hàm. Nhớ là tên hàm phân biệt hoa-thường nha
- Con số sau ký tự @ là thứ tự của hàm mà bạn đã viết trong Module ở trên
- Lưu tệp soạn thảo này vào thư mục chứa file Project DLL mà ta đã tạo ở bước 3 với tên trùng với tên DLL mà ta muốn tạo, phần mở rộng là .DEF. Ví dụ: nếu ta muốn tạo ra 1 dll có tên là MyLibrary.DLL thì file DEF này sẽ phải lưu với tên là MyLibrary.DEF
- Bây giờ bạn có thể Make cái Project bạn đã tạo ở bước 3 được rồi. từ menu File, chọn Make như với các Project bình thường khác
- Sau khi được file DLL rồi thì chắc là các bạn đã biết cách sử dụng nó như thế nào:
- + Copy file DLL vào cùng thư mục với Project muốn sử dụng nó
+ Khai báo như sau để Import hàm của DLL vào Project
- Private Declare Function Add Lib "MyLibrary.dll" (ByVal a As Integer, ByVal b As Integer) As Integer