DLL - Panduan Cepat

Tautan dinamis adalah mekanisme yang menghubungkan aplikasi ke perpustakaan pada saat berjalan. Perpustakaan tetap berada dalam file mereka sendiri dan tidak disalin ke dalam file aplikasi yang dapat dijalankan. DLL menautkan ke aplikasi saat aplikasi dijalankan, bukan saat dibuat. DLL mungkin berisi tautan ke DLL lain.

DLL sering kali ditempatkan di file dengan ekstensi berbeda seperti .EXE, .DRV, atau .DLL.

Keuntungan DLL

Diberikan di bawah ini adalah beberapa keuntungan memiliki file DLL.

Menggunakan lebih sedikit sumber daya

File DLL tidak dimuat ke dalam RAM bersama dengan program utama; mereka tidak menempati ruang kecuali diperlukan. Ketika file DLL diperlukan, itu dimuat dan dijalankan. Misalnya, selama pengguna Microsoft Word mengedit dokumen, file DLL printer tidak diperlukan dalam RAM. Jika pengguna memutuskan untuk mencetak dokumen, maka aplikasi Word menyebabkan file DLL printer dimuat dan dijalankan.

Mempromosikan arsitektur modular

DLL membantu mempromosikan pengembangan program modular. Ini membantu Anda mengembangkan program besar yang membutuhkan beberapa versi bahasa atau program yang membutuhkan arsitektur modular. Contoh program modular adalah program akuntansi yang memiliki banyak modul yang dapat dimuat secara dinamis pada saat run-time.

Membantu penyebaran dan pemasangan yang mudah

Ketika sebuah fungsi dalam DLL memerlukan pembaruan atau perbaikan, penyebaran dan penginstalan DLL tidak memerlukan program untuk dihubungkan kembali dengan DLL. Selain itu, jika beberapa program menggunakan DLL yang sama, maka semuanya mendapat manfaat dari pembaruan atau perbaikan. Masalah ini dapat terjadi lebih sering saat Anda menggunakan DLL pihak ketiga yang diperbarui atau diperbaiki secara berkala.

Aplikasi dan DLL dapat ditautkan ke DLL lain secara otomatis, jika tautan DLL ditentukan di bagian IMPOR dari file definisi modul sebagai bagian dari kompilasi. Jika tidak, Anda dapat memuatnya secara eksplisit menggunakan fungsi Windows LoadLibrary.

File DLL Penting

  • COMDLG32.DLL - Mengontrol kotak dialog.

  • GDI32.DLL - Berisi banyak fungsi untuk menggambar grafik, menampilkan teks, dan mengatur font.

  • KERNEL32.DLL - Berisi ratusan fungsi untuk pengelolaan memori dan berbagai proses.

  • USER32.DLL- Berisi berbagai fungsi antarmuka pengguna. Terlibat dalam pembuatan jendela program dan interaksinya satu sama lain.

Pertama, kita akan membahas masalah dan persyaratan yang harus Anda pertimbangkan saat mengembangkan DLL Anda sendiri.

Jenis DLL

Saat Anda memuat DLL dalam aplikasi, dua metode penautan memungkinkan Anda memanggil fungsi DLL yang diekspor. Dua metode penautan adalah:

  • tautan dinamis waktu muat, dan
  • penautan dinamis run-time.

Penautan dinamis waktu muat

Dalam penautan dinamis waktu muat, aplikasi membuat panggilan eksplisit ke fungsi DLL yang diekspor seperti fungsi lokal. Untuk menggunakan penautan dinamis waktu muat, berikan file header (.h) dan file library impor (.lib), saat Anda mengompilasi dan menautkan aplikasi. Saat Anda melakukan ini, linker akan menyediakan sistem dengan informasi yang diperlukan untuk memuat DLL dan menyelesaikan lokasi fungsi DLL yang diekspor pada waktu pemuatan.

Tautan dinamis waktu proses

Dalam penautan dinamis runtime, aplikasi memanggil fungsi LoadLibrary atau fungsi LoadLibraryEx untuk memuat DLL saat runtime. Setelah DLL berhasil dimuat, Anda menggunakan fungsi GetProcAddress, untuk mendapatkan alamat fungsi DLL yang diekspor yang ingin Anda panggil. Saat Anda menggunakan penautan dinamis runtime, Anda tidak memerlukan file library impor.

Daftar berikut menjelaskan kriteria aplikasi untuk memilih antara penautan dinamis waktu muat dan penautan dinamis waktu proses:

  • Startup performance : Jika kinerja permulaan awal aplikasi penting, Anda harus menggunakan penautan dinamis run-time.

  • Ease of use: Dalam tautan dinamis waktu muat, fungsi DLL yang diekspor mirip dengan fungsi lokal. Ini membantu Anda memanggil fungsi-fungsi ini dengan mudah.

  • Application logic: Dalam penautan dinamis runtime, aplikasi dapat bercabang untuk memuat modul yang berbeda sesuai kebutuhan. Ini penting saat Anda mengembangkan versi banyak bahasa.

Titik Masuk DLL

Saat Anda membuat DLL, Anda dapat secara opsional menentukan fungsi titik masuk. Fungsi titik masuk dipanggil saat proses atau utas menempelkan dirinya sendiri ke DLL atau melepaskan diri dari DLL. Anda dapat menggunakan fungsi titik masuk untuk menginisialisasi atau menghancurkan struktur data seperti yang dipersyaratkan oleh DLL.

Selain itu, jika aplikasi multithread, Anda dapat menggunakan penyimpanan lokal thread (TLS) untuk mengalokasikan memori yang bersifat pribadi ke setiap thread dalam fungsi titik masuk. Kode berikut adalah contoh fungsi titik masuk DLL.

BOOL APIENTRY DllMain(
HANDLE hModule,	// Handle to DLL module DWORD ul_reason_for_call, LPVOID lpReserved )  // Reserved
{
   switch ( ul_reason_for_call )
   {
      case DLL_PROCESS_ATTACHED:
      // A process is loading the DLL.
      break;
      case DLL_THREAD_ATTACHED:
      // A process is creating a new thread.
      break;
      case DLL_THREAD_DETACH:
      // A thread exits normally.
      break;
      case DLL_PROCESS_DETACH:
      // A process unloads the DLL.
      break;
   }
   return TRUE;
}

Ketika fungsi titik masuk mengembalikan nilai FALSE, aplikasi tidak akan mulai jika Anda menggunakan tautan dinamis waktu muat. Jika Anda menggunakan tautan dinamis runtime, hanya DLL individual yang tidak akan dimuat.

Fungsi titik masuk seharusnya hanya melakukan tugas inisialisasi sederhana dan tidak boleh memanggil fungsi pemuatan atau penghentian DLL lainnya. Misalnya, dalam fungsi titik masuk, Anda tidak boleh secara langsung atau tidak langsung memanggilLoadLibrary fungsi atau LoadLibraryExfungsi. Selain itu, Anda tidak boleh memanggilFreeLibrary berfungsi saat proses dihentikan.

WARNING: Dalam aplikasi multithread, pastikan bahwa akses ke data global DLL disinkronkan (aman untuk thread) untuk menghindari kemungkinan kerusakan data. Untuk melakukannya, gunakan TLS untuk menyediakan data unik untuk setiap utas.

Mengekspor Fungsi DLL

Untuk mengekspor fungsi DLL, Anda dapat menambahkan kata kunci fungsi ke fungsi DLL yang diekspor atau membuat file definisi modul (.def) yang mencantumkan fungsi DLL yang diekspor.

Untuk menggunakan kata kunci fungsi, Anda harus mendeklarasikan setiap fungsi yang ingin Anda ekspor dengan kata kunci berikut:

__declspec(dllexport)

Untuk menggunakan fungsi DLL yang diekspor dalam aplikasi, Anda harus mendeklarasikan setiap fungsi yang ingin Anda impor dengan kata kunci berikut:

__declspec(dllimport)

Biasanya, Anda akan menggunakan satu file header yang memiliki define pernyataan dan ifdef pernyataan untuk memisahkan pernyataan ekspor dan pernyataan impor.

Anda juga dapat menggunakan file definisi modul untuk menyatakan fungsi DLL yang diekspor. Saat Anda menggunakan file definisi modul, Anda tidak perlu menambahkan kata kunci fungsi ke fungsi DLL yang diekspor. Dalam file definisi modul, Anda mendeklarasikanLIBRARY pernyataan dan EXPORTSpernyataan untuk DLL. Kode berikut adalah contoh file definisi.

// SampleDLL.def
//
LIBRARY "sampleDLL"

EXPORTS
   HelloWorld

Tulis Contoh DLL

Di Microsoft Visual C ++ 6.0, Anda dapat membuat DLL dengan memilih file Win32 Dynamic-Link Library jenis proyek atau MFC AppWizard (dll) Jenis proyek.

Kode berikut adalah contoh DLL yang dibuat dalam Visual C ++ dengan menggunakan jenis proyek Perpustakaan Dynamic-Link Win32.

// SampleDLL.cpp

#include "stdafx.h"
#define EXPORTING_DLL
#include "sampleDLL.h"

BOOL APIENTRY DllMain( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved )
{
   return TRUE;
}

void HelloWorld()
{
   MessageBox( NULL, TEXT("Hello World"), 
   TEXT("In a DLL"), MB_OK);
}
// File: SampleDLL.h
//
#ifndef INDLL_H
#define INDLL_H

#ifdef EXPORTING_DLL
extern __declspec(dllexport) void HelloWorld() ;
#else
extern __declspec(dllimport) void HelloWorld() ;
#endif

#endif

Memanggil Sample DLL

Kode berikut adalah contoh dari proyek Aplikasi Win32 yang memanggil fungsi DLL yang diekspor di SampleDLL DLL.

// SampleApp.cpp 

#include "stdafx.h"
#include "sampleDLL.h"

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR     lpCmdLine,  int       nCmdShow)
{ 	
   HelloWorld();
   return 0;
}

NOTE : Dalam penautan dinamis waktu muat, Anda harus menautkan pustaka impor SampleDLL.lib yang dibuat saat Anda membuat proyek SampleDLL.

Dalam runtime dynamic linking, Anda menggunakan kode yang mirip dengan kode berikut untuk memanggil fungsi DLL yang diekspor SampleDLL.dll.

...
typedef VOID (*DLLPROC) (LPTSTR);
...
HINSTANCE hinstDLL;
DLLPROC HelloWorld;
BOOL fFreeDLL;

hinstDLL = LoadLibrary("sampleDLL.dll");
if (hinstDLL != NULL)
{
   HelloWorld = (DLLPROC) GetProcAddress(hinstDLL, "HelloWorld");
	
   if (HelloWorld != NULL)
   (HelloWorld);

   fFreeDLL = FreeLibrary(hinstDLL);
}
...

Ketika Anda menyusun dan menautkan aplikasi SampleDLL, sistem operasi Windows mencari DLL SampleDLL di lokasi berikut dalam urutan ini:

  • Folder aplikasi

  • Folder saat ini

  • Folder sistem Windows (File GetSystemDirectory fungsi mengembalikan jalur folder sistem Windows).

  • Folder Windows (File GetWindowsDirectory fungsi mengembalikan jalur folder Windows).

Untuk menggunakan DLL, DLL harus didaftarkan dengan memiliki referensi yang sesuai yang dimasukkan di Registri. Terkadang referensi Registry rusak dan fungsi DLL tidak dapat digunakan lagi. DLL dapat didaftarkan ulang dengan membuka Start-Run dan memasukkan perintah berikut:

regsvr32 somefile.dll

Perintah ini mengasumsikan bahwa somefile.dll ada di direktori atau folder yang ada di PATH. Jika tidak, jalur lengkap DLL harus digunakan. File DLL juga dapat dibatalkan pendaftarannya dengan menggunakan sakelar "/ u" seperti yang ditunjukkan di bawah ini.

regsvr32 /u somefile.dll

Ini dapat digunakan untuk mengaktifkan dan menonaktifkan layanan.

Beberapa alat tersedia untuk membantu Anda memecahkan masalah DLL. Beberapa di antaranya dibahas di bawah ini.

Ketergantungan Walker

Alat Dependency Walker (depends.exe) dapat secara rekursif memindai semua DLL dependen yang digunakan oleh program. Ketika Anda membuka program di Dependency Walker, Dependency Walker melakukan pemeriksaan berikut ini:

  • Memeriksa DLL yang hilang.
  • Memeriksa file program atau DLL yang tidak valid.
  • Memeriksa apakah fungsi impor dan fungsi ekspor cocok.
  • Memeriksa kesalahan ketergantungan melingkar.
  • Memeriksa modul yang tidak valid karena modul tersebut untuk sistem operasi yang berbeda.

Dengan menggunakan Dependency Walker, Anda dapat mendokumentasikan semua DLL yang digunakan program. Ini dapat membantu mencegah dan memperbaiki masalah DLL yang mungkin terjadi di masa mendatang. Ketergantungan Walker terletak di direktori berikut ini ketika Anda menginstal Microsoft Visual Studio 6.0:

drive\Program Files\Microsoft Visual Studio\Common\Tools

Pemecah Masalah Universal DLL

Alat Pemecah Masalah Universal DLL (DUPS) digunakan untuk mengaudit, membandingkan, mendokumentasikan, dan menampilkan informasi DLL. Daftar berikut menjelaskan utilitas yang membentuk alat DUPS:

  • Dlister.exe - Utilitas ini menghitung semua DLL di komputer dan mencatat informasi ke file teks atau ke file database.

  • Dcomp.exe - Utilitas ini membandingkan DLL yang terdaftar dalam dua file teks dan menghasilkan file teks ketiga yang berisi perbedaan.

  • Dtxt2DB.exe - Utilitas ini memuat file teks yang dibuat dengan menggunakan utilitas Dlister.exe dan utilitas Dcomp.exe ke dalam database dllHell.

  • DlgDtxt2DB.exe - Utilitas ini menyediakan versi antarmuka pengguna grafis (GUI) dari utilitas Dtxt2DB.exe.

Ingatlah tip berikut ini saat menulis DLL:

  • Gunakan konvensi panggilan yang tepat (C atau stdcall).

  • Perhatikan urutan argumen yang benar yang diteruskan ke fungsi tersebut.

  • JANGAN PERNAH mengubah ukuran array atau string gabungan menggunakan argumen yang diteruskan langsung ke suatu fungsi. Ingat, parameter yang Anda lewati adalah data LabVIEW. Mengubah ukuran larik atau string dapat mengakibatkan crash dengan menimpa data lain yang disimpan dalam memori LabVIEW. Anda DAPAT mengubah ukuran array atau menggabungkan string jika Anda meneruskan LabVIEW Array Handle atau LabVIEW String Handle dan menggunakan kompiler Visual C ++ atau kompiler Symantec untuk mengkompilasi DLL Anda.

  • Saat meneruskan string ke suatu fungsi, pilih jenis string yang benar untuk diteruskan. C atau Pascal atau LabVIEW string Handle.

  • String pascal dibatasi hingga 255 karakter.

  • String C diakhiri NULL. Jika fungsi DLL Anda mengembalikan data numerik dalam format string biner (misalnya, melalui GPIB atau port serial), fungsi tersebut dapat mengembalikan nilai NULL sebagai bagian dari string data. Dalam kasus seperti itu, melewatkan array bilangan bulat pendek (8-bit) adalah yang paling andal.

  • Jika Anda bekerja dengan array atau string data, SELALU berikan buffer atau array yang cukup besar untuk menampung hasil apa pun yang ditempatkan di buffer oleh fungsi kecuali Anda meneruskannya sebagai pegangan LabVIEW, dalam hal ini Anda dapat mengubah ukurannya menggunakan CIN fungsi di bawah kompiler Visual C ++ atau Symantec.

  • Buat daftar fungsi DLL di bagian EKSPOR dari file definisi modul jika Anda menggunakan _stdcall.

  • Buat daftar fungsi DLL yang dipanggil oleh aplikasi lain di bagian EKSPOR file definisi modul atau untuk menyertakan kata kunci _declspec (dllexport) dalam deklarasi fungsi.

  • Jika Anda menggunakan compiler C ++, ekspor fungsi dengan pernyataan .C. {} Extern di file header Anda untuk mencegah pengubahan nama.

  • Jika Anda menulis DLL Anda sendiri, Anda tidak boleh mengkompilasi ulang DLL saat DLL dimuat ke memori oleh aplikasi lain. Sebelum mengompilasi ulang DLL, pastikan bahwa semua aplikasi yang menggunakan DLL tersebut telah dikeluarkan dari memori. Ini memastikan bahwa DLL itu sendiri tidak dimuat ke dalam memori. Anda mungkin gagal membangun kembali dengan benar jika Anda lupa ini dan kompiler Anda tidak memperingatkan Anda.

  • Uji DLL Anda dengan program lain untuk memastikan bahwa fungsi (dan DLL) berfungsi dengan benar. Mengujinya dengan debugger kompiler Anda atau program C sederhana di mana Anda dapat memanggil fungsi dalam DLL akan membantu Anda mengidentifikasi apakah kemungkinan kesulitan melekat pada DLL atau terkait LabVIEW.

Kami telah melihat bagaimana menulis DLL dan bagaimana membuat program "Hello World". Contoh itu pasti memberi Anda gambaran tentang konsep dasar pembuatan DLL.

Di sini, kami akan memberikan penjelasan tentang cara membuat DLL menggunakan Delphi, Borland C ++, dan lagi VC ++.

Mari kita ambil contoh ini satu per satu.

  • Bagaimana menulis dan memanggil DLL dalam Delphi

  • Membuat DLL dari Borland C ++ Builder IDE

  • Membuat DLL di Microsoft Visual C ++ 6.0