DLL dengan Delphi


Blog Entry DLL dengan Delphi Nov 13, ’09 10:18 AM
for everyone

Baru belajar DLL niy ceritanya.. Udah tua begini belajar DLL. Mungkin buat teman-teman yang sudah berkesempatan belajar dan bertahun-tahun bermain-main dengannya hanya tersenyum simpul melihat saya baru belajar DLL. Hare gene??

Tapi tidak mengapa. Islam mengajari bahwa hidup adalah belajar. Minal madi, ilal lahdi. Dari buaian hingga liang kubur. Selama belum ada bendera kuning, kita mesti terus belajar, dan lebih baik lagi, berbagi dengan sesama. Toh kita bisa belajar karena ada orang lain yang mendahului kita belajar dan berbagi ilmu kan? Kita tahu karena ada orang yang berbagi kepada kita. Itulah yang coba saya lakukan. Karena saya tidak ingin menunggu bertahun-tahun sebelum membagikannya, saya mencoba menuliskannya sekarang. Jika ada teman-teman yang ingin mengoreksi atau menambahkan, saya dengan senang hati akan menerimanya sebagai tambahan proses belajar itu sendiri.

Buat teman-teman yang tidak tertarik dengan dunia pemrograman, tidak perlu meneruskan untuk membaca tulisan ini, silakan ke http://wishknew.multiply.com/tag/movies untuk membaca tulisan saya tentang hobi saya yang lain, menonton film.

Ok, DLL adalah sebuah file yang biasa terdapat di platform sistem operasi berbasis Windows dari Microsoft, merupakan singkatan dari Dynamic Link Library. Sejarah lengkap DLL bisa dibaca di http://en.wikipedia.org/wiki/.dll. Intinya DLL menyediakan mekanisme bagi programmer untuk berbagi kode program, resource, maupun data atau kombinasinya untuk program lain yang membutuhkan hal yang sama. Dalam kasus saya kali ini, saya mempunyai sebuah kelas di Delphi yang algoritmanya bertumbuh. Jika suatu ketika nanti saya ingin menyempurnakan algoritmanya tanpa mengubah antarmukanya, saya ingin hanya memperbaharui sebagian kecil program saya, tidak seluruhnya. Nah hal ini dimungkinkan apabila kelas yang saya buat itu disimpan di sebuah DLL. Jika lain kali saya ingin memperbaharui implementasinya atau melakukan perbaikan kesalahan (bugs), maka saya tidak perlu mendistribusikan aplikasi executablenya selurunhya sekaligus. Saya bisa memperbaharui hanya DLLnya saja.

Itu idenya. Ok, sekarang bagaimana membuatnya? Seperti biasa, duduk manis di depan laptop, bertanya kepada Mbah Google. Mbah memberi banyak sekali petunjuk. Salah satu di antaranya ada di delphi.about .com yaitu http://delphi.about.com/od/windowsshellapi/a/dll_basics.htm dan juga ada di http://delphi.about.com/library/weekly/aa010901a.htm yang membandingkannya dengan BPL (Borland Package Library). BPL disebut lebih cocok jika memang kita selalu menggunakan Delphi. Nah jadinya bingung deh mau memilih DLL atau BPL. Akhirnya bertanya lagi ke stackoverflow di http://stackoverflow.com/questions/1700366/loading-a-delphi-object-run-time-using-bpl

Wah dari sebagian besar mereka justru tidak menganjurkan menggunakan BPL karena tergantung versi Delphinya. Lebih banyak mudharat daripada manfaat kata mereka. Ya sudah. Kita ikuti kata mereka-mereka, dan sekarang tambah yakin mau mencoba menggunakan DLL.

Dari petunjuk mereka, kuncinya adalah membuat sebuah fungsi yang mengembalikan instance dari sebuah interface. Nah itulah yang dicoba. Dan alhamdulillah berhasil, thanx to Riza yang dah nemenin mencoba-coba membuatnya.

library TestDLL;

{ Important note about DLL memory management: ShareMem must be the

first unit in your library’s USES clause AND your project’s (select

Project-View Source) USES clause if your DLL exports any procedures or

functions that pass strings as parameters or function results. This

applies to all strings passed to and from your DLL–even those that

are nested in records and classes. ShareMem is the interface unit to

the BORLNDMM.DLL shared memory manager, which must be deployed along

with your DLL. To avoid using BORLNDMM.DLL, pass string information

using PChar or ShortString parameters. }

uses

ShareMem,

SysUtils,

Classes;

{$R *.res}

type

THelloWorld = class(TObject)

public

class function SayHelloWorld: TStringBuilder; stdcall;

end;

{ THelloWorld }

function HelloWorld: TStringBuilder; stdcall;

begin

Result := THelloWorld.SayHelloWorld;

end;

class function THelloWorld.SayHelloWorld: TStringBuilder;

begin

Result := TStringBuilder.Create;

Result.Append(‘Hello World’);

Result.Append(#13#10 + ‘Hurray…’);

end;

exports HelloWorld;

begin

end.

·Kode di atas merupakan program untuk membentuk DLL. Strukturnya mirip file Delphi Project yang biasa kita dapatkan ketika membuat project baru. Bedanya kalau project diawali dengan kata kunci Program sedangkan DLL diawali dengan Library

·Pastikan semua fungsi yang akan dibuat publik di DLL memiliki tambahan kata kunci stdcal dan nanti pas akan dipanggil juga harus sama. Kalau kelupaan, bisa gak jalan!

Contoh:

function HelloWorld: TStringBuilder; stdcall; //awas case sensitive

·Di bagian bawah program sebutkan semua fungsi yang akan diexport, contoh:

exports HelloWorld;

Ok sekarang kita buat contoh di mana kita menggunakan interface, karena di kelas yang akan menggunakan object DLL, kita tidak punya skeleton dari definisi kelasnya. Karenanya kita perlu bantuan interface, sebangsa kelas abstract yang merupakan kontrak mati bagi semua kelas yang mengimplementasikannya untuk mengimplementasikan semua fungsi dalam interface tersebut.

Kelas DLL kita akan berupa:

library DLLNoHell;

{ Important note about DLL memory management: ShareMem must be the

first unit in your library’s USES clause AND your project’s (select

Project-View Source) USES clause if your DLL exports any procedures or

functions that pass strings as parameters or function results. This

applies to all strings passed to and from your DLL–even those that

are nested in records and classes. ShareMem is the interface unit to

the BORLNDMM.DLL shared memory manager, which must be deployed along

with your DLL. To avoid using BORLNDMM.DLL, pass string information

using PChar or ShortString parameters. }

uses

SysUtils,

Classes,

unitInterface,

Dialogs;

type

B = class(TInterfacedObject, IB)

public

procedure HelloB;

end;

A = class(TInterfacedObject, IA)

public

procedure HelloA;

function GetB: IB;

end;

{$R *.res}

{ B }

procedure B.HelloB;

begin

showMessage(‘I am B’);

end;

{ A }

function A.GetB: IB;

begin

Result := B.Create;

end;

procedure A.HelloA;

begin

ShowMessage(‘I am A’);

end;

function GetInstanceOfA: IA; stdcall;

begin

Result := A.Create;

end;

exports GetInstanceOfA;

begin

end.

Unit interface kita berupa:

unit unitInterface;

interface

uses Classes;

type

IB = interface

procedure HelloB;

end;

IA = interface

procedure HelloA;

function GetB: IB;

end;

implementation

end.

Dan kelas tester yang kita miliki:

unit unitTester;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, unitInterface, StdCtrls;

type

TForm4 = class(TForm)

Label1: TLabel;

procedure FormCreate(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

var

Form4: TForm4;

function GetInstanceOfA: IA stdcall; external ‘DLLNoHell.dll’;

implementation

{$R *.dfm}

procedure TForm4.FormCreate(Sender: TObject);

var

instanceA: IA;

instanceB: IB;

begin

instanceA := GetInstanceOfA;

instanceA.HelloA;

instanceB := instanceA.GetB;

instanceB.HelloB;

end;

end.

Perhatikan kata kunci stdcall harus sama persis dengan yang ada di DLL. Melupakan stdcall akan menyebabkan kegagalan mencari fungsi yang dimaksud. Ok.. semoga cukup jelas.

Kalau ada yang ingin menambahkan atau bertanya please feel free to do so.

Tinggalkan Balasan

Isikan data di bawah atau klik salah satu ikon untuk log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout /  Ubah )

Foto Google+

You are commenting using your Google+ account. Logout /  Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout /  Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout /  Ubah )

w

Connecting to %s