Làm Quen Với DDL Đại Học KHTP TP.HCM

13 276 0
Làm Quen Với DDL Đại Học KHTP TP.HCM

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

LÀM QUEN VỚI DLL Văn Chí Nam vcnam@fit.hcmuns.edu.vn Khoa Công nghệ Thông tin, trường ĐH KHTN TP.HCM Phiên cập nhật ngày 15/11/2005 Giới thiệu DLL gì? DLL viết tắt cụm từ Dynamic Link Library DLL file nhị phân chứa nhiều hàm thực thi cho phép ứng dụng khác gọi đến Một DLL nhiều ứng dụng sử dụng đồng thời Các hàm DLL phân chia làm loại: export (hàm xuất, hàm cho phép ứng dụng bên sử dụng), internal (hàm nội bộ, hàm sử dụng nội DLL) Ưu điểm việc sử dụng DLL Sử dụng DLL làm cho kích thước ứng dụng nhỏ Nhiều ứng dụng dùng chung DLL, đó, tiết kiệm nhớ (thông thường, ứng dụng có liệu riêng, chia sẻ mã lệnh) Khi không sử dụng, giải phóng DLL khỏi nhớ Khi cần nâng cấp, cần thay file DLL, file chương trình khác không bị ảnh hưởng Khuyết điểm việc sử dụng DLL Đòi hỏi lập trình viên phải thực nhiều thao tác bình thường Phân loại DLL MFC hỗ trợ loại DLL: DLL dạng mở rộng (Extension DLL) dạng bình thường (Regular DLL) DLL dạng mở rộng (Extension DLL) Extension DLL cho phép sử dụng lại lớp từ MFC cho phép ứng dụng khác sử dụng lớp (dạng “export”) Các ứng dụng MFC có định nghĩa _AFXEXT sử dụng với Extension DLL mà Extension DLL liên kết với DLL MFC theo dạng liên kết động Regular DLL Regular DLL sử dụng với ứng dụng MFC ứng dụng dạng Win32 Application Regular DLL cho phép “export” hàm dạng C/C++ không cho phép “export” lớp có DLL Regular DLL liên kết với DLL MFC theo cách: liên kết tĩnh (statically linking) liên kết động (dynamic linking) Liên kết tĩnh có nghĩa đoạn mã DLL MFC chèn vào Regular DLL hàm tương ứng sử dụng đến Việc liên kết tĩnh với thư viện MFC làm cho DLL (Regular DLL) có kích lớn Để giảm kích thước DLL xuống, liên kết dạng liên kết động Với dạng này, đoạn mã thư việc MFC không chèn trực tiếp vào Regular DLL nạp lên cần sử dụng đến Tuy nhiên, với dạng liên kết này, phải kèm DLL MFC cần sử dụng với Regular DLL Cách thức gọi DLL ứng dụng Gọi lúc ứng dụng nạp (load-time) Với cách thức gọi DLL theo kiểu này, ứng dụng nạp DLL lên nhớ ứng dụng có sử dụng đến hàm thực thi DLL trình thực thi hay không Chính vậy, điều dẫn đến bất tiện: tốn nhớ nạp DLL, ứng dụng hoạt động trường hợp DLL không tồn Tuy nhiên, cách dễ thực lập trình viên bắt đầu sử dụng DLL Gọi lúc thực thi (run-time) Cách gọi DLL kiểu vượt qua khó khăn gặp phải kiểu gọi DLL lúc ứng dụng nạp (load-time): lập trình viên định cần phải nạp DLL lên nhớ, ứng dụng thực thi (với chức bổ sung khác) DLL không tồn Tuy nhiên, điểm khó khăn cách gọi nằm chỗ người lập trình viên tốn nhiều công sức cho việc nạp DLL, gọi hàm DLL Minh hoạ xây dựng regular DLL Trong minh hoạ đây, minh hoạ cách tạo lập Regular DLL Visual C++ 6.0 (sử dụng dạng liên kết động với DLL MFC) DLL chứa hai hàm tính toán (cộng nhân) cho phép ứng dụng khác gọi đến Minh hoạ có hàm xuất (export) Tạo ứng dụng DLL dạng Regular - Chọn New\Projects\MFC AppWizard (dll) - Đặt tên project (Project name) chọn lựa vị trí thư mục thích hợp (Location) Chọn Regular DLL using shared MFC DLL Step of Nhấn Finish để hoàn tất việc tạo lập project dạng Regular DLL Visual C++ 6.0 phát sinh số tập tin số đoạn mã cho ứng dụng Khai báo hàm xuất Dạng hàm tổng quát extern "C" declspec(dllexport) TenKieuTraVe TenHam(CacThamSo); Đối với ứng dụng có nhiều hàm cần xuất, định nghĩa giá trị thay sau: #define extern "C" declspec(dllexport) EXPORT Khi đó, hàm tổng quát có dạng: EXPORT TenKieuTraVe TenHam(CacThamSo); Ví dụ: Khai báo hai hàm xuất Cong, Nhan extern "C" declspec(dllexport) int Cong(int a, int b); extern "C" declspec(dllexport) int Nhan(int a, int b); Hoặc EXPORT int Cong(int a, int b); EXPORT int Nhan(int a, int b); Khai báo hàm xuất đặt tập tin header (.h) tập tin thi hành (.cpp) Không thiết đặt khai báo hàm xuất tập tin header Khai báo hàm nội Hàm nội DLL khai báo đặc biệt so với việc khai báo hàm ứng dụng thông thường Viết phần thực thi cho hàm xuất Khi viết phần thực thi cho hàm xuất cần lưu ý đặt macro AFX_MANAGE_STATE thân hàm Macro cần thiết hàm có gọi (sử dụng) đối tượng từ thư viện MFC Trong hàm xuất sử dụng đến đối tượng MFC không cần sử dụng macro Tuy nhiên, lời khuyên là: “nên đạt macro vào đầu thân hàm xuất” Ví dụ: Phần thực thi cho hàm Cong extern "C" declspec(dllexport) int Cong(int a, int b) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); return a + b; } Phần thực thi cho hàm Nhan extern "C" declspec(dllexport) int Nhan (int a, int b) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); return a*b; } Biên dịch DLL giống biên dịch ứng dụng bình thường khác Sau biên dịch thành công, tập tin dll tương ứng tạo kèm với tập tin có tập tin thư viện lib Chúng minh hoạ cách sử dụng hai tập tin phần sau viết Minh hoạ tạo ứng dụng sử dụng DLL Phần viết minh hoạ việc sử dụng DLL vừa tạo phần Cách thức gọi DLL ứng dụng gọi DLL lúc nạp ứng dụng (kiểu loadtime) Đây cách thức nạp DLL đơn giản, dễ thực Tuy nhiên, hạn chế cách thức nạp DLL không tìm thấy DLL tương ứng lúc nạp ứng dụng ứng dụng thoát không thực Tạo lập ứng dụng Ứng dụng tạo lập theo dạng dialog-based với control đặt dialog mô tả Đặt biến đại diện tương ứng với control nhập hình Thêm tập tin lib vào project ứng dụng Như đề cập phần trên, sau biên dịch Regular DLL, có tập tin quan trọng cần lưu giữ: lib dll File lib chứa khai báo hàm có DLL, file sử dụng cách gọi DLL kiểu load-time, hỗ trợ cho trình biên dịch ứng dụng File dll chứa mã thực thi hàm DLL, hàm nạp vào nhớ dll gọi Đầu tiên, cần phải chép file lib dll vào thư mục chứa project ứng dụng gọi DLL Thêm file lib vào project cách: - Chọn Project\Add to Project\ Files - Chọn Files of type Library Files (.lib) - Chọn file cần thêm vào (RegularDLL.lib) nhấn OK Khai báo hàm nhập ứng dụng Những hàm xuất (export) DLL hàm nhập (import) ứng dụng Chúng ta cần khai báo hàm nhập cần thiết, khai báo tất hàm mà DLL “xuất” Dạng hàm khai báo tổng quát extern "C" declspec(dllimport) TenKieuTraVe TenHam(CacThamSo); Ví dụ: extern "C" declspec(dllimport) int Cong(int a, int b); Trong trường hợp, khai báo hàm xuất DLL đặt file header (.h) include file vào project Tuy nhiên, nhớ chỉnh dllexport khai báo xuất thành dllimport khai báo nhập Viết mã thực thi cho chức Hàm xử lý kiện nhấn vào nút Cong void CUsingRegularDLLDlg::OnCong() { // TODO: Add your control notification handler code here UpdateData(); m_iZ = Cong(m_iX, m_iY); UpdateData(FALSE); } Hàm xử lý kiện nhấn vào nút Nhan void CUsingRegularDLLDlg::OnNhan() { // TODO: Add your control notification handler code here UpdateData(); m_iZ = Nhan(m_iX, m_iY); UpdateData(FALSE); } Hàm xử lý kiện nhấn vào nút Thoat void CUsingRegularDLLDlg::OnThoat() { // TODO: Add your control notification handler code here CDialog::OnCancel(); } Lưu ý Mỗi nội dung hàm DLL có thay đổi phải cập nhật DLL cho ứng dụng cách ghi đè file DLL cũ ứng dụng sử dụng Đối với kiểu gọi DLL load-time, DLL có thay đổi cách khai báo hàm xuất, phải xoá lib cũ khỏi project ứng dụng thêm (cập nhật) lib cho project ứng dụng Minh hoạ tạo ứng dụng gọi DLL kiểu run-time Sử dụng kiểu gọi DLL loại run-time có nhiều đặc điểm thuận lợi so với gọi DLL kiểu load-time: - Không cần file lib kèm lúc tạo project ứng dụng - DLL nạp lên cần sử dụng (thay nạp lúc ứng dụng gọi thực thi kiểu load-time) Việc dẫn đến khả uyển chuyển sử dụng DLL: chương trình thực với số chức bị thiếu (do DLL), thay đổi DLL ứng dụng thực thi,… Tuy nhiên, cách gọi có bất tiện tốn nhiều công sức cho việc viết phần thực thi gọi hàm Tạo ứng dụng Ứng dụng tạo kiểu dialog-based giống phần minh hoạ phía Các hàm nhập cần thiết Trong ứng dụng này, sử dụng hai hàm xuất DLL là: Cong, Nhan Hai hàm có dạng: int Cong(int a, int b); int Nhan(int a, int b); Chính vậy, định nghĩa trỏ hàm MYPROC cho hai hàm sau: typedef int (*MYPROC)(int, int); Cách thức nạp hàm từ DLL: - Nạp DLL hàm LoadLibrary Kiểm tra xem DLL có tồn không cách xem kết trả có khác NULL hay không - Nạp hàm cần thiết hàm GetProcAddress Kiểm tra việc gọi hàm thành công hay không - Giải phóng DLL khỏi nhớ hàm FreeLibrary Ví dụ: HINSTANCE hInstance; hInstance = LoadLibrary(TENTAPTINDLL); MYPROC Ham; if (hInstance == NULL) { //Tap tin DLL khong ton tai return; } Ham = (MYPROC)GetProcAddress(hInstance, HamCanNap); if (Ham == NULL) { //Ham khong ton tai hoac khong dung return; } FreeLibrary(hInstance); Viết phần thực thi cho hàm Hàm xử lý kiện nhấn nút Cong void CUsingRegularDLLRuntimeDlg::OnCong() { // TODO: Add your control notification handler code here HINSTANCE hInstance; hInstance = LoadLibrary("RegularDLL.dll"); MYPROC Cong; if (hInstance == NULL) { MessageBox("Tap tin RegularDLL.dll khong ton tai","Loi"); return; } Cong = (MYPROC)GetProcAddress(hInstance, "Cong"); if (Cong == NULL) { MessageBox("Khong ton tai ham Cong DLL.","Loi"); return; } UpdateData(); m_iZ = Cong(m_iX, m_iY); UpdateData(FALSE); FreeLibrary(hInstance); } Hàm xử lý kiện nhấn nút Nhan void CUsingRegularDLLRuntimeDlg::OnNhan() { // TODO: Add your control notification handler code here HINSTANCE hInstance; hInstance = LoadLibrary("RegularDLL.dll"); MYPROC Nhan; if (hInstance == NULL) { MessageBox("Tap tin RegularDLL.dll khong ton tai","Loi"); return; } Nhan = (MYPROC)GetProcAddress(hInstance, "Nhan"); if (Nhan == NULL) { MessageBox("Khong ton tai ham Nhan DLL.","Loi"); return; } UpdateData(); m_iZ = Nhan(m_iX, m_iY); UpdateData(FALSE); FreeLibrary(hInstance); } Thử nghiệm Thực thử nghiệm để hiểu rõ cách gọi DLL theo kiểu run-time - Không chép DLL vào vị trí ứng dụng sử dụng DLL Chạy ứng dụng không? Có thực thi chức (Cong, Nhan) ứng dụng không? - Không thoát ứng dụng Chép DLL vào vị trí ứng dụng sử dụng DLL Thực thi chức ứng dụng không? Debug với DLL Khi cần debug hàm DLL, thực thi DLL dựa ứng dụng sử dụng DLL Trong ví dụ minh hoạ đây, sử dụng DLL (Regular.dll) ứng dụng (UsingRegularDLL.exe) tạo lập sẵn để thực việc debug - Tạo breakpoint vị trí cần debug (hàm Cong) - Thực thi DLL chế độ Debug Khi thực thi, môi trường lập trình yêu cầu chọn lựa ứng dụng sử dụng DLL để thực Có thể xuất lỗi sau: Lỗi xuất ứng dụng không tìm thấy DLL để thực thi Cần phải chép DLL vào thư mục ứng dụng chạy debug lại cho DLL lại Khi đó, xuất hình debug cho DLL sau: Tài liệu tham khảo “DLL tutorial”, (MindCracker) MSDN [...]... được không? Có thực thi được các chức năng (Cong, Nhan) của ứng dụng không? - Không thoát ứng dụng Chép DLL vào cùng vị trí của ứng dụng sử dụng DLL Thực thi được các chức năng của ứng dụng không? Debug với DLL Khi cần debug hàm trong DLL, chúng ta sẽ thực thi DLL dựa trên một ứng dụng sử dụng DLL Trong ví dụ minh hoạ dưới đây, chúng tôi sử dụng DLL (Regular.dll) và ứng dụng (UsingRegularDLL.exe) được

Ngày đăng: 28/10/2015, 17:49

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan