-
15-02-2011, 05:02 PM #1Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Tìm hiểu về thư viện liên kết động trên Win32 API
Mặc dù time cũng ko nhiều, cơm áo gạo tiền, học hành, tình yêu, ........... nhưng mình xin dành chút tut tiếp về Lập trình trong windows với thư viện liên kết động
Total length : 11 chap
Start day : 2/15/2011 9:08AM
End day : 2/27/2011 (one chap per day)
Yêu cầu :
+ Ko thích hoặc biết oy đừng đọc rồi châm nọ châm kia, chỉ tiếp nhận các ý kiến đóng góp mang tính xây dựng.
+ Tool để lập trình :
Mã:full : http://forums.congdongcviet.com/showthread.php?t=33540 hoặc portable : http://forums.congdongcviet.com/showthread.php?t=46528
Thư viện liên kết độngThư viện liên kết động (Dynamic-Link Library-DLL, còn được gọi là thư viện động - dynalink lib - hoặc module thư viện) là một trong các phẩn tử cấu trúc quan trọng nhất của Windows. Hầu hết các file trong bộ sản phẩm windows, các sản phẩm ứng dụng trên windows là các module chương trình (*.exe) hoặc các module thư viện (*.dll). Đặc điểm của thư viện liên kết động là có tính khả chuyển cao, nhờ đó mà một DLL có thể được gắn vào một hoặc nhiều phần mềm khác nhau.
Như bạn thấy, chương trình trong windows là một file khả thi (PE File - Portable Executable File Format ) thường tạo một hoặc nhiều cửa sổ và sử dụng vòng lặp thông điệp để nhận nhập liệu người dùng. các thư viện liên kết động thường không thực thi trực tiếp và chúng thường không nhận các thông điệp. Chúng là các file tách riêng chứa các hàm có thể được các chương trình gọi và các dll khác thực hiện các tác vụ nào đó
Hình 1 : Trong windows thì các file dll tập trung nhiều nhất tại thư mục system32
Chap 1 : Khái niệm về thư viện
Thư viện liên kết động được đưa vào hoạt động chỉ khi một module khác gọi một trong các hàm của thư viện hoặc đưa ra quyết định load chúng
Thuật ngữ "dynamic linking", liên kết động chỉ tiếng trình mà windows sử dụng để liên kết gọi hàm trong một module với một hàm thực trong module thư viện. dynamic linking xảy ra vào thời gian chạy.
"Static linking", liên kết tĩnh xảy ra trong quá trình biên dịch ứng dụng, khi trình biên dịch liên kết các file module đối tượng (*.OBJ) khác nhau, các thư viện run time (*.LIB), và 1 file tài nguyên (*.RES) đã biên dịch lại thành chương trình của bạn
Hình 2 : hình ảnh quá trình link (static link)
KERNEL32.DLL, USER32.DLL và GID32.DLL và các file trình điều khiển khác nhau như KEYBOARD.DRV , SYSTEM.DRV , MOUSE.DRV, trình điều khiển máy in, màn hình ... đều là thư viện liên kết động. Chúng là các thư viện mà tất cả các chương trình windiows có thể sử dụng
Trích wikipedia : Ưu điểm của thư viện liên kết động
Giảm không gian sử dụng của bộ nhớ
Hàm và dữ liệu trong các DLL được chia sẻ bởi các ứng dụng dùng nó. Như trong ví dụ ở trên, các ứng dụng Winword, Microsoft Excel, Internet Explorer sẽ dùng chung một hàm print() đã được biên dịch thành mã máy và để trong một DLL nào đó, mà không cần phải bao gồm toàn bộ mã nguồn của hàm. Bên cạnh đó, ta cũng có thể giảm được dung lượng bộ nhớ của chương trình tùy vào cách dùng các hàm DLL (Run-time hay Load-time, sẽ được trình bày sau): ứng dụng của ta sẽ chỉ nạp các hàm này khi nào dùng đến.
Mã trong DLL nằm trong khu vực chỉ cho đọc (read-only) và được nạp vào các trang nhớ đánh dấu read-only. Nó cho phép hệ thống ánh xạ DLL vào trong không gian địa chỉ nhớ của các tiến trình sử dụng nó. Và như vậy, DLL được nạp chỉ một lần, và nếu một tiến trình yêu cầu sử dụng nó, hệ điều hành chỉ việc ánh xạ DLL tới không gian địa chỉ của ứng dụng gọi DLL.
<font color="Red"> Giảm Swapping (tráo đổi)
Ta tưởng tượng có hai tiến trình sử dụng cùng một DLL, một tiến trình kết thúc công việc của nó và thoát ra. Nhưng DLL sẽ không gỡ bỏ ra khỏi bộ nhớ vì DLL quản lý thời gian tồn tại của nó bằng cách giữ một bộ đếm tham khảo cho các tiến trình sử dụng nó. Mỗi khi có một tiến trình nào đó yêu cầu sử dụng DLL, bộ đếm tham khảo sẽ tăng giá trị của nó lên 1; còn khi có một tiến trình gỡ bỏ không sử dụng nữa thì bộ đếm lại giảm đi 1. DLL sẽ tự động xóa bỏ ra khỏi bộ nhớ chừng nào bộ đếm tham khảo trở về 0, trạng thái cho biết không còn có tiến trình nào sử dụng DLL nữa.
Bây giờ giả sử có một tiến trình bắt đầu chạy và yêu cầu hệ thống nạp một DLL hiện đang được dùng bởi một ứng dụng đã chạy trước đó. Chuyện gì sẽ xảy ra? Liệu hệ thống có nạp DLL một lần nữa không? Hiển nhiên là không, vì DLL được định nghĩa ra để có thể dùng chung giữa các ứng dụng khác nhau. Thành phần đã nạp DLL có tất cả các hàm và dữ liệu của nó trong bộ nhớ và hệ thống sẽ chỉ phải ánh xạ chúng tới không gian địa chỉ của tiến trình mới cho chúng hoạt động. Nó liên quan đến việc đọc các hàm và dữ liệu DLL từ trên đĩa.
<font color="Red"> Có thể đóng gói và đưa vào chương trình khác
Khi đã xây dựng được một DLL với các chức năng hợp lý, ta có thể sử dụng nó trong bất cứ ứng dụng nào mà ta cảm thấy thích hợp. Ví dụ trong một ứng dụng nhỏ, ta có tập hợp các hàm chuyển đổi giá trị từ String sang ngày tháng và đóng gói nó vào trong một DLL. Khi đó, ở một ứng dụng khác, khi có nhu cầu chuyển đổi như trên, thì ta sẽ không phải viết lại các hàm hoặc đính kèm mã nguồn của các hàm đó vào chương trình đó nữa mà sử dụng trực tiếp DLL mà ta đã biên dịch.
Tạo ra khả năng tương tác giữa các ngôn ngữ lập trình
Một ứng dụng có thể sử dụng các DLL viết bằng bất cứ ngôn ngữ lập trình nào. Các nhà phát triển phần mềm chỉ việc đóng gói các module của mình vào trong một DLL với ngôn ngữ ưa thích, sau đó module này có thể được sử dụng trong các ứng dụng viết bằng C++ hay Visual Basic.
Mặc dù hầu hết các ngôn ngữ lập trình đều hỗ trợ việc sử dụng thư viện liên kết động, nhưng lại có rất ít ngôn ngữ lập trình cho phép tạo ra chúng. Với việc sử dụng DLL, người ta có thể tập trung nhiều hơn vào các xử lý logic của hệ thống, mà không cần phải quan tâm đến những xử lý thông thường, mà nếu phát triển từ đầu, sẽ chi phí rất nhiều thời gian và công sức. Các công việc này đã được thực hiện bởi một người nào đó, và đóng gói dưới dạng các DLL.
Dễ dàng đưa ra sự hỗ trợ sau khi đã chuyển giao ứng dụng cho khách hàng
Nếu như ta phát hiện có một số thành phần trong ứng dụng cần phải được thay đổi và sự thay đổi này cần phải được cập nhật cho khách hàng. Đóng gói và phân phối lại toàn bộ sản phẩm đã bán cho tất cả các khách hàng của chúng ta là một công việc hết sức khó khăn. Tuy nhiên ta có thể tránh được điều này nếu như ứng dụng của ta được thiết kế tốt thành các module và đóng gói chúng trong các DLL. Khi một module nào đó cần thay đổi, ta chỉ việc đóng gói lại DLL chứa module đó và gửi tới khách hàng, cho họ cập nhật.</font></font>View more random threads:
- hồn trương ba, da hàng thịt
- Inject Code Cave
- Sử dụng DLL files trong Visual C++ 2005
- Mix code giữa .NET và WINAPI
- Tìm hiểu về thư viện liên kết động trên Win32 API
- Hướng dẫn thao tác với FTP server theo cách thủ công
- Thuật toán và giải thuật tạo serial của IDM [Hướng dẫn chi tiết]
- OpenMP for beginner!!!
- Nghệ thuật Traps Code trong Visual C++
- Lập trình đồ họa | Từng bước xây dựng cho mình một thư viện đồ họa - GDrawing
-
15-02-2011, 05:39 PM #2Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Chap 2 : Thư viện với nhiều ý nghĩaMột phần nhầm lẫn chung quang các thư viên liên kết động do sự xuất hiện của từ "library" trong một số ngữ cách khác nhau. Ngoài thư viện liên kết động chúng ta còn nói tới object lib (thư viện đối tượng) và import lib (thư viện nhập)
Thư viện đối tượng là 1 file có đuôi mở rộng .LIB chữa mã được thêm vào file EXE của chương trình trong tiến trình được gọi là liên kết tĩnh khi bạn chạy bộ linker. Ví dụ trong Visual C++ thư viện đối tượng run time C thông thường bạn liên kết với chương trình của mình là LIBC.LIB
Thư viện nhập là một dạng đặc biệt của file thư viện đối tượng. Giống như các thư viện đối tượng, các thư viện nhập cũng có đuôi mở rộng là .LIB và được bộ liên kết sử dụng để phân giải các lệnh gọi hàm trong mã nguồn của bạn, tuy nhiên các thư viện nhập này lại ko chứa mã. Thay vào đó chúng cung cấp bộ liên kết với các thông tin cần thiết để thiết lập bảng tái. định vị trong file EXE của bạn, qua đó liên kết động với DLL cần thiết.
File Kernel32.lib, User32.lib và Gdi32.lib được gộp trong bộ Visual Studio là các thư viện nhập cho các hàm Windows. Nếu bạn gọi hàm Rectangle trong một chương trình, GDI32.lib cho LINKER biết hàm này ở trong thư viện liên kết động GDI32.DLL tại địa chỉ nào, như thế nào. Thông tin này đi vào file .EXE của bạn để windows có thể thực hiện liên kết động chương trình của bạn với thư viện GDI32.DLL
Hình 3 : Thư viện nhập
Các thư viện đối tượng và thư viện nhập chỉ được sử dụng trong quá trình biên dịch chương trình. Các thư viện liên kết động được sử dụng trong quá trình chạy. Thư viện DLL phải tồn tại trong bộ nhớ vật lý để sử dụng. Khi windows cần nạp DLL, hệ điều hành sẽ tìm tại thư mục chứa file exe -> thư mục hiện hành -> thư mục hế thống-> thư mục chứa trong biến path
chú ý : thư mục chứa file exe ko phải lúc nào cũng là thư mục hiện hành
-
16-02-2011, 02:55 PM #3Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Chap 3 : Một số ví dụ về Dll đơn giản
Ví dụ 1 : Với Visual C++ 6 Bước 1 :
Ví dụ 1 : Với Visual C++ 6 Bước 2 :
(chap 3 còn dài nữa)
-
17-02-2011, 11:24 AM #4Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Chap 3 : Một số ví dụ về Dll đơn giản
Ví dụ 2 :
Ở ví dụ thứ 2 này chúng ta sẽ tạo DLL được gọi là EDRLIB.DLL (ý là easy drawing routines, hi hi hi), cũng là 1 dll ví dụ nên chỉ chứa 1 hàm EdrCenterText, nhưng lần này chúng ta sẽ làm 1 cách hoàn thiện,đầy đủ , tương thích
cách làm việc với Visual C++ 6 vẫn thế</font>, mình sẽ upload ảnh đối với visual studio 2010 ultimate
và source code file edrlib.cpp như sau
Mã:/************************************************************************//* EDRLIB.C Easy Drawing Routine Library module *//************************************************************************/#include <windows.h>#include "edrlib.h" BOOL APIENTRY DllMain( HMODULE hModule,DWORD ul_reason_for_call,LPVOID lpReserved){ switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE;} EXPORT BOOL CALLBACK EdrCenterTextA (HDC hdc, PRECT prc, PCSTR pString){ int iLength ; SIZE size ; iLength = lstrlenA(pString) ; GetTextExtentPoint32A(hdc, pString, iLength, &size); return TextOutA(hdc, (prc->right - prc->left - size.cx) / 2, (prc->bottom - prc->top - size.cy) / 2, pString, iLength );} EXPORT BOOL CALLBACK EdrCenterTextW (HDC hdc, PRECT prc, PCWSTR pString){ int iLength ; SIZE size ; iLength = lstrlenW(pString) ; GetTextExtentPoint32W(hdc, pString, iLength, &size); return TextOutW(hdc, (prc->right - prc->left - size.cx) / 2, (prc->bottom - prc->top - size.cy) / 2, pString, iLength );}
Làm tương tự như đối với VC++6 chỉ khác ở 2 vấn đề sau
<font color="Red">+ new project : File -> new -> VC++ -> Win32 project -> Windows Application -> finish
+ Để thêm file lib vào project, ta chỉ cần chuột phải vào project, vào add -> add existing file -> add file lib của mình vào
và đây là source chạy thử file DLL của bạn
(code win32 application với visual studio 2010, các bạn tạo new project rồi sửa source thành thế này là được)
Mã:// test.cpp : Defines the entry point for the application.// #include "stdafx.h"#include "test.h"#include "edrlib.h" #define MAX_LOADSTRING 100 // Global Variables:HINSTANCE hInst; // current instanceTCHAR szTitle[MAX_LOADSTRING]; // The title bar textTCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name // Forward declarations of functions included in this code module:ATOM MyRegisterClass(HINSTANCE hInstance);BOOL InitInstance(HINSTANCE, int);LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow){ UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: Place code here. MSG msg; HACCEL hAccelTable; // Initialize global strings LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_TEST, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); // Perform application initialization: if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_TEST)); //EdrCenterText() // Main message loop: while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return (int) msg.wParam;} //// FUNCTION: MyRegisterClass()//// PURPOSE: Registers the window class.//// COMMENTS://// This function and its usage are only necessary if you want this code// to be compatible with Win32 systems prior to the 'RegisterClassEx'// function that was added to Windows 95. It is important to call this function// so that the application will get 'well formed' small icons associated// with it.//ATOM MyRegisterClass(HINSTANCE hInstance){ WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TEST)); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = MAKEINTRESOURCE(IDC_TEST); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassEx(&wcex);} //// FUNCTION: InitInstance(HINSTANCE, int)//// PURPOSE: Saves instance handle and creates main window//// COMMENTS://// In this function, we save the instance handle in a global variable and// create and display the main program window.//BOOL InitInstance(HINSTANCE hInstance, int nCmdShow){ HWND hWnd; hInst = hInstance; // Store instance handle in our global variable hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE;} //// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)//// PURPOSE: Processes messages for the main window.//// WM_COMMAND - process the application menu// WM_PAINT - Paint the main window// WM_DESTROY - post a quit message and return////LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){ int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; RECT rect; switch (message) { case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // Parse the menu selections: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); // TODO: Add any drawing code here... GetClientRect(hWnd,&rect); EdrCenterText(hdc,&rect,L"a"); EndPaint(hWnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0;} // Message handler for about box.INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam){ UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE;}
-
19-02-2011, 12:49 PM #5Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Thật tình mà nói, để học theo chap 3 cũng chả đơn giản gì với newbie (mặc dù nó đã ở đơn giản nhất ). Do mình cũng chỉ là 1 newbie nên mình hiểu mà [IMG]images/smilies/11.gif[/IMG][IMG]images/smilies/11.gif[/IMG][IMG]images/smilies/11.gif[/IMG]
theo cá nhân mình, các bạn mới thì nên download VC++6.0 portable về và thử theo hướng dẫn ví dụ 1
[IMG]images/smiliesot_talking.gif[/IMG][IMG]images/smiliesot_talking.gif[/IMG]
đối với ví dụ 2 dành cho vs2010 mình làm rất sơ lược và chỉ giới thiệu cái cần thiết, nên việc theo dõi l
Trước hết, mặc dù như ở chap 2 chúng ta đã phân loại DLL như đuổi mở rộng của của Windows, nó cũng là đuôi mở rộng của chương trình ứng dụng của bạn, Mọi thứ DLL thực hiện đều nhân danh ứng dụng. Ví dụ tất cả bộ nhớ được cấp phát đều được ứng dụng làm chủ. Nhiều ứng dụng có thể sử dụng dll đồng thời, nhưng dưới windows các ứng dụng này đươc bảo vệ để tránh gây trở ngại cho nhau
Nhiều tiến trình có thể dùng chung cùng mã trong thư viện liên kết động. Tuy nhiên dữ liệu được duy trì bởi DLL khác nhau đối với từng tiến trình. Mỗi tiến trình có một không gian đỉa chỉ riêng cho bất kì dữ liệu nào DLL sử dụng. Việc dùng chung các bộ nhớ giữ các tiến trình đòi hỏi kĩ thuật, và chúng ta sẽ nghiên cứu kĩ thuật này ngay bây giờ [IMG]images/smilies/kiss.gif[/IMG][IMG]images/smilies/kiss.gif[/IMG][IMG]images/smilies/kiss.gif[/IMG]
Chap 4 : Chia sẻ bộ nhớ qua DLL</font></font>
Kĩ thuật chia sẽ bộ nhớ qua dll đã được chia sẻ tại đây với hình ảnh minh họa cụ thể: hãy đọc sơ qua bài viết này trước khi đọc tiếp
http://forums.congdongcviet.com/showthread.php?t=35213
Mình xin trình bày cách 2 không thông qua DEF file,
Bước 1 : tạo 1 dll project
Bước 2 : trong source code, bạn hãy đình nghĩa section được chia sẻ như sau
Mã:#define EXPORT extern "C" __declspec(dllexport) #pragma data_seg("shared") int qdelay=0; #pragma data_seg() #pragma comment(linker,"/SECTION:shared,RWS") EXPORT void APIENTRY setqdelay(int n){ qdelay=n;}EXPORT int APIENTRY getqdelay(){ return qdelay;}
Chú ý 2 : Các bạn phải khởi tạo giá trị cho biến tại vùng nhớ chia sẻ, nếu ko các biến này sẽ được đưa vào đoạn chưa được khởi tạo thông thường thay vì trong shared của chúng ta
(đặc biệt chú ý, điều này rất có ý nghĩa với .net dll hoặc các DLL làm với các IDE ver cao)
Chú ý 3 : Trong cách 1 của anh pt, chúng ta sử dung file .DEF để định nghĩa thuộc tính của vùng nhớ này, tuy nhiên, về sau thì DEF file lại ít được sử dụng hơn, vì thế ta định nghĩa luôn trong source code của mình
#pragma comment(linker,"/SECTION:shared,RWS")
RWS ở đây là READ WRITE SHARED , là thuộc tính của vùng nhớ này
để hiểu sâu hơn về vấn đề này, tra MSDN về FILE MAPPING hoặc chờ tut sắp tới của mình tại cộng đồng c việt
Chú ý 4 : tại các ứng dụng thì ko thể truy cập trực tiếp tới biến đó đâu, do đó mình cần làm các hàm điểu khiển (bộ get/set như trong ví dụ trên)
Chú ý 5 : trong thực tế, khi 1 file dll có thể có >5 hoặc >10 ứng dụng sẽ load nó thì ta cần nghiên cứu thêm về FILE MAPPING và các Lock, Unlock để tránh xung đột
Chú ý 6 : ngày trước mình luôn cố gắng đi tìm 1 tài liệu đầy đủ về dll nhưng thật là khó , có thì lại là tiếng anh, ko thì chỉ lướt sơ qua
dần dần trải nghiệm mình đã hiểu, ko có cái gọi là đầy đủ đâu, mình hãy tự trải nghiệm, hãy bắt đầu ngay bây giờ bạn à,
thực tế sẽ cho mình kinh nghiệm
mình cũng ko hi vọng tut này trở thành đầy đủ được, nhưng mình hi vọng nó sẽ cho bạn 1 điểm bắt đầu tốt nhất........ nên mình sẽ viết 1 cách đơn giản nhất và viết ra tất cả những gì mình đã học được, những kinh nghiệm của mình
<font color="red">Tip more : ở đây mình đã sử thêm 1 vấn đề mới, đó là từ khóa APIENTRY
ở đây tại sao mình lại viết thêm từ khóa này ?
mục đích của mình đó là chỉ rõ ra hàm này có cách calling là APIENTRY,
APIENTRY hoàn toàn như CALLBACK, chúng là 1
sau này bạn hãy thêm từ khóa APIENTRY hoặc CALLBACK trong mỗi hàm của DLL nhé,
nó sẽ làm tường minh thêm code của bạn và tránh được sự bất đồng về calling mặc định giữa các hãng khác nhau, ver khác nhau
(<font color="DarkOrange">và nhớ viết đúng chỗ nữa nhé, sau kiểu dữ liệu, trước tên hàm)
-
19-02-2011, 05:42 PM #6Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Chap 5 : DLL và 1 số vấn đề liên quanCác bạn biết đấy, module thư viện ko nhận các thông điệp. Tuy nhiên, module thư viện có thể gọi GetMessage và PeekMessage. Các thông điệp mà thư viện lấy ra được từ hàng đợi thông điệp của ứng dụng chứ ko phải lấy ra từ hàng đợi thông điệp của hệ thống. Nói chung là thư viện sẽ làm việc nhân danh chương trình gọi nó, một nguyên tắc lưu giữ cho hầu hết các hàm windows mà thư viện làm việc
Thư viện động có thể nạp tài nguyên chẳng hạn như biểu tượng, chuỗi, bitmap) từ file thư viện hoặc từ file chương trình gọi thư viện. Các hàm nạp dòi handle của instance , mình có thể truyền instance của dll hoặc exe gọi chúng
Đăng kí cửa sổ và tạo ra các cửa sổ trong 1 dll có thể hơi phức tạp vì cả lớp windows và hàm CreateWindow cũng đòi handle của instance. Mặc dù mình có thể dùng instance của dll thì thông điệp vẫn đi vào hàng đợi thông điệp của ứng dụng. nên nếu đăng kí/tạo cửa sổ ta nên dùng hInstance của cái thằng exe gọi nó
Do các hộp thoại modal có thông điệp dạng truy hồi nên ta có thể tạo hôp thoại modal trong thư viện (xài hàm DialogBox ý )với tham số hwndParent=NULL
Next chap :
chap 6 : Thư viện liên kết động ko có thư viện nhập
chap 7 : Các thư viện tài nguyên (end tut, kết thúc sớm hơn dự tính vì các chap sau mình sẽ cắt ra làm 1 loạt tut adv khác )
-
21-02-2011, 04:15 PM #7Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Chap 6 : Thư viện liên kết động ko có thư viện nhập
Còn gì tuyệt vời hơn khi chúng ta có 1 thư viện liên kết động và .h và .lib của nó , tuy loằng ngoằng nhiều file nhưng lại cho ta thấy sự tiện lợi rõ ràng !
đó là trong sử dụng, chúng ta sau khi import vào thì cứ thế mà sử đụng, tất cả đều đã có cú pháp rõ ràng
Tuy nhiên như thế này, ngày trước, khi còn học cấp 3, tôi rất thích viết trainer cho game, mơ ước của tôi đó, có mấy cái game, bạn tôi (hơn tuổi, hồi đó đang học dh), anh ý viết 1 cái trainer, nài nỉ mãi để theo học anh ý, cuối cùng, a ý cho 1 file dll, trong này có source hack rồi, tìm hiểu nhanh cách xài với vb đi là ok!!
chà chà, có mỗi file dll thì bít làm gì nhỉ ?
Bây giờ, tuy chưa biết nhiều về lập trình lắm, chúng ta vẫn có cơ may viết hack game online bằng cách sử dụng lậu file dll của người khác đã viết, he he (tất nhiên là chả ai cho ta .h và .lib của nó đâu)
Thật ra bản thân dll là 1 sản phẩm đã đóng gói rồi, nên việc sử dụng mà cứ phải có file lib hoàn toàn là ko bắt buộc!
Thay vì nạp DLL lúc nạp chương trình vào bộ nhớ, chúng ta hoàn toàn có thể optional cả lúc nạp thư viện nữa!
.......
hi hi, nội chung chap này đã được người bạn AlexF trình bày dễ hiểu tại đây , mình ko trình bày nữa, chỉ dẫn nhập như thế thôi.
http://forums.congdongcviet.com/showthread.php?t=9390
-
21-02-2011, 05:29 PM #8Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Chap 7 : Các thư viện tài nguyên
Một hàm bất kì trong thư viện liên kết động mà một chương trình ứng dụng khác hoặc thư viện khác muốn sử dụng đều phải là hàm trích xuất, tuy nhiên lại chả có quy định nào bắt 1 DLL phải có hàm xuất, dll chả cần đến hàm xuất , trong windows 7 cũng có nhiều dll như thế ví dụ như các file có tên là *res.dll : imageres.dll chứa 218 icon (chắc là nhiều hơn với các version sau)
và nhiều thư viện khác còn chưa cả video như shell32.dll
rồi getuname.dll với 13480 chuỗi kí tự !
Tại sao lại thế, sao ta ko để nguyên nó ở thư mục, như thế có đơn giản hay ko ?
Ta làm các file này để làm gì ?
+ sự đóng gói : bạn có muốn làm ra 1 phần mềm mà loằng ngoằng nhiều file khó quản lý ko ? Mình nhớ có cái game là attlan, hày gì ý, game này gần 10k file, ôi trời ạ, chỉ copy thôi đã thấy chán rồi, chả muốn chơi, (tự mình thấy nó quá noob).
Như game võ lâm, toàn bộ tài nguyên nó đều đánh cụm và nén trong *.pak
còn audition thì nén trong *.acv (thật ra với cái game aution này cũng có nhiều cái thật là củ chuối, ngày xưa VTC chia sẻ bộ cài là bộ file .rar, giải nén ra được 1 file cài đặt .exe, khi bật file .exe này để cài thì nó xả ra 1 file .msi rồi chính thức bắt đầu cài!!!! Chuối cả rừng)
+ an toàn tài nguyên : bạn có muốn người ta dễ dàng lấy tài nguyên của bạn sau vài cái click chuột để xài ko ?
+ bảo mật : bạn có muốn làm ra 1 ứng dụng rồi người ta tha hồ sửa chữa thành của họ ko ?
Hì hì, thui bỏ qua mấy cái dẫn nhập loằng ngoằng, mình xin trình bày luôn cách làm
Bước 1. mylib.dll
+ Tạo 1 project win32dll như lần trước tên mylib
+ Tạo file mylib.cpp
Mã:#include <windows.h> BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason ,LPVOID reserved){ return TRUE;}
+Add tài nguyên vào : bạn vào Insert chọn Resource
bạn hãy add cho mình 1 vài cái ảnh bitmap (*.bmp) vào file dll này nhé
Bước 2. test file dll vừa tạo
(ví dụ với Icon, Currsor,... các bạn làm tương tự thôi mà)
Để show bitmap trong dll ta vừa tạo ra chúng ta vẫn dựa vào ID của Resource bitmap đó, khác ở mỗi chỗ đó là ở hàm load , tham số đầu tiên sẽ là handle của file DLL
Mã:HINSTANCE hLib= LoadLibrary (....);............LoadIcon(hLib,IDI_ABC);.............LoadBitmap(hLib,IDB_XENG);............LoadBitmap(hLib,1004); //1004 chính là mã của Resource , nếu ko có .h của DLL thì ta phải dùng mã này//vậy làm thế nào để biết mã này?????????? xem chap tiếp
-
21-02-2011, 06:05 PM #9Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Chap 8 : Nội soi DLLThật ra thì mình muốn được viết thật nhiều , thật dài dài như các tut của mình nhưng mà
+ dạo này mình nhiều bài tập quá, sắp tốt nghiệp mà + tình yêu suốt ngày "anh ơi"
+ kiến thức mình còn nông cạn
nên loạt tut này của mình hơi ngắn, ko thật đầy đủ, nhưng mình hi vọng nó cho bạn 1 điểm khởi đầu với dll thật tốt và dễ hiểu nhất
Vấn đề là, giả sử sau khi mình có 1 dll của người khác làm rồi, ko có .h, ko có .lib thì mình làm thế nào để xài đây ? Bên trong nó có cái gì
mình xin giới thiệu tool sau :
1. Xem tài nguyên + mã tài nguyên trong 1 file dll :
http://forums.congdongcviet.com/atta...2&d=1282111046
2. Xem hàm export trong 1 file dll
http://forums.congdongcviet.com/atta...1&d=1298304094
64 bit :
http://forums.congdongcviet.com/atta...1&d=1298304289
-
27-02-2011, 05:08 PM #10Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Chap 9 : Làm thế nào để export variable từ DLL</font></font>
hôm trước viết quên mất cái này, giờ add thêm vào
Cách 1 : đơn giản dễ hiểu
Bước 1 : Khai báo trong DLL
Mã:_declspec( dllexport ) int i=2;_declspec( dllexport ) int *j=new int(2);_declspec( dllexport ) char *sz="langman";
Mã:_declspec( dllimport ) int i; _declspec( dllimport ) int *j; _declspec( dllimport ) char *sz;
Cách 2 : Bố cục
Bước 1 : Khai báo trong source DLL
Mã:int i = 1; int *j = 2; char *sz = "langman";
Mã:EXPORTS i DATA j DATA sz DATA
chú ý
1. Với IDE cùi bắp cổ điển thì phải dùng từ khóa CONSTANT thay cho từ khóa DATA
và nó trích xuất ra lại là address nên khi dùng sẽ đổi là
Mã:extern int *i; extern int **j; extern char **sz;
Bổ xung thông tin vào chap 3 -> Ví dụ 1 -> Bước 1 : <font size="5">Ta có 1 cách thêm file .lib vào trong project cực nhanh, ko cần vào setting coment loằng ngoằng như thế bằng cách : add luôn file lib vào project
Pallet nhựa Long An đã trở thành một trong những lựa chọn phổ biến cho nhu cầu vận chuyển và lưu trữ hàng hóa trong nhiều ngành công nghiệp. Với đặc tính nhẹ nhàng, chắc chắn và dễ vận chuyển, các...
Thanh lý pallet nhựa Long An giá rẻ