Senin, 15 September 2014

Membuat DLL Sederhana dengan MinGW


Dynamic Link Library merupakan file yang di link bersama program-program lain untuk memberikan kemudahan dalam melakukan suatu pekerjaan. Sebelum ada DLL, dulu program di link bersama dengan static library, sehingga ukuran program menjadi lebih besar. Dengan adanya fitur shared memory, diciptakanlah dynamic link library. Library cukup diload satu kali, lalu semua program bisa menggunakan satu library itu secara bersamaan. Jika ingin menggunakan fungsi dari library, program tidak perlu mengambil kode dari library tersebut saat proses linking, program hanya mengaitkan nama fungsi saja kedalam program. Ketika program dijalankan, sistem operasi akan meload library dan mencari alamat pointer fungsi yang diinginkan.

Let's start
Walaupun DLL hanya bertugas menyediakan fungsi bagi program yang membutuhkan, tapi DLL juga memiliki entry-point atau fungsi main(). Bedanya, fungsi utama ini dipanggil hanya untuk keperluan inisialisasi dan de-inisialisasi.
Berikut ini adalah bentuk fungsi entry-point nya...

BOOL WINAPI DllMain (HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved)
{
    switch (dwReason)
    {
        case DLL_PROCESS_ATTACH:
            //Kode
            break;

        case DLL_PROCESS_DETACH:
            //Kode
            break;

        case DLL_THREAD_ATTACH:
            //Kode
            break;

        case DLL_THREAD_DETACH:
            //Kode
            break;
    }
    return TRUE;
}


hDll
Argumen pertama adalah nomor handle DLL. Digunakan untuk memanipulasi DLL jika diperlukan saat inisialisasi atau saat de-inisialisasi.

dwReason
dwReason adalah kode yang memberitahukan informasi ketika DllMain dipanggil. Informasi ini dapat berupa salah satu dari empat berkut ini..
  • DLL_PROCESS_ATTACH : DllMain dipanggil setelah program meload DLL. Saat inilah kita melakukan inisialisasi.
  • DLL_PROCESS_DETACH : DllMain dipanggil saat program berhenti menggunakan DLL. Saat hal ini terjadi, de-inisialisasi bisa dilakukan bila diperlukan.
  • DLL_THREAD_ATTACH : DllMain dipanggil saat proses membuat thread baru.
  • DLL_THREAD_DETACH : DllMain dipanggil saat proses telah menghentikan thread.
lpReserved
Nilai argumen ini dapat dikategorikan menjadi 2:
  • Jika dwReason = DLL_PROCESS_ATTACH, lpReserved bernilai 0 jika library diload secara dynamic. Jika bukan 0, library diload secara static.
  • Jika dwReason = DLL_PROCESS_DETACH, lpReserved bernilai 0 jika library dihentikan secara dynamic dengan fungsi FreeLibrary(). Jika bukan 0, library dihentikan secara static, yaitu bersamaan dengan berhentinya program.

Return value
Sebaiknya DllMain mengembalikan nilai 1(TRUE), jika tidak program akan dianggap mengalami error saat meload library. Tapi, jika kita ingin melakukan inisialisasi atau de-inisialisasi tertentu dan hasilnya tidak mendukung, mungkin mengembalikan nilai FALSE akan lebih baik.

Let’s coding
Kode yang kita tulis pertama adalah kode untuk membuat DLL itu sendiri. Dalam DllMain, kita mendeteksi argumen dwReason untuk membuktikan apakah DLL_PROCESS_ATTACH dan DLL_PROCESS_DETACH benar-benar dieksekusi pada waktu yang benar. Untuk melakukannya, kita menggunakan fungsi MessageBox(). Sementara itu, kita juga membuat FungsiA() dan FungsiB() yang bisa dipanggil oleh program.


Nama file : contoh_dll.c

#include <windows.h>

BOOL WINAPI DllMain(HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved)
{
    switch (dwReason)
    {
        case DLL_PROCESS_ATTACH:
            MessageBox(0,"DLL_PROCESS_ATTACH", "dwReason", MB_OK);
            break;

        case DLL_PROCESS_DETACH:
            MessageBox(0,"DLL_PROCESS_ATTACH", "dwReason", MB_OK);
            break;
    }
    return TRUE;
}

void FungsiA()
{
    MessageBox(0,"Pesan dari FungsiA()", "Hey", MB_OK);
}

void FungsiB()
{
    MessageBox(0,"Pesan dari FungsiB()", "Hey", MB_OK);
}


Agar FungsiA() dan FungsiB() bisa di pakai oleh program dan bisa diakses dengan mudah, kita dianjurkan untuk membuat file header yang isinya berupa deklarasi bentuk FungsiA() dan FungsiB().




Nama file: contoh_dll.h

//deklarasi FungsiA() dan FungsiB()

void FungsiA();
void FungsiB();


Untuk mengompile file ini mejadi dll, gunakan perintah berikut..
gcc -Wall -shared contoh_dll.c -o contoh_dll.dll

Setelah membuat DLL, sekarang kita bisa mengujinya dengan kode program berikut. Kode ini akan mencoba memanggil FungsiA() sekaligus FungsiB().


Nama file: pakai_dll.c

#include <stdio.h>
#include <conio.h>
#include "contoh_dll.h"

int main()
{
    printf("Program mulai\n");
    FungsiA();
    FungsiB();
   
    printf("Press any key to exit\n");
    getch();
    return 0;
}


Untuk mengompilenya, gunakan perintah berikut..
gcc -Wall pakai_dll.c contoh_dll.dll -o pakai_dll.exe

Download source
Jika kode di atas belum jelas, anda bisa mendownloadnya dalam link berikut ini.


https://app.box.com/s/qcnndlhofzw13lo3crb6
 
Demo


Load disqus comments

0 comments