Chào mừng đến với Diễn đàn lập trình - Cộng đồng lập trình.
Trang 1 của 3 123 CuốiCuối
Kết quả 1 đến 10 của 25
  1. #1

    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 động
    Thư 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.




    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
    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 đó

    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 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>

  2. #2
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Chap 2 : Thư viện với nhiều ý nghĩa
    Mộ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.

    Hình 3 : Thư viện nhập
    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


    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


  3. #3
    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)

  4. #4
    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        );}
    Bước 2 Test DLL

    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;}

  5. #5
    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ú ý 1 : shared là tên của section sau khi biên dịch, bạn hoàn toàn có thể tùy chọn tên (đặt tên tùy thích). Nhưng thật tình, ta nên, rất nên, đặt nó với cái tên là "shared" hoặc ".shared"

    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
    )

  6. #6
    Chap 5 : DLL và 1 số vấn đề liên quan
    Cá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 )

  7. #7
    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

  8. #8
    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;}
    + Tạo file mylib.rc
    +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

  9. #9
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Chap 8 : Nội soi DLL
    Thậ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

  10. #10
    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";
    Bước 2 : Khai báo trong ứng dụng xài dll

    Mã:
          _declspec( dllimport ) int i;      _declspec( dllimport ) int *j;      _declspec( dllimport ) char *sz;
    Các này bắt buộc là phải có file lib, dùng như hướng dẫn ở chap trước




    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";
    Bước 2 : khai báo trong file .def của dll

    Mã:
       EXPORTS      i  DATA      j  DATA      sz DATA
    Bước 3 : sử dụng như cũ






    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;
    2. <font color="Red">Visual C++ 6.0 ko phải là cùi pắp







    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



 

 
Trang 1 của 3 123 CuốiCuối

Quyền viết bài

  • Bạn Không thể gửi Chủ đề mới
  • Bạn Không thể Gửi trả lời
  • Bạn Không thể Gửi file đính kèm
  • Bạn Không thể Sửa bài viết của mình
  •