Dinamik DLL

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
morphine39
Üye
Mesajlar: 35
Kayıt: 02 May 2009 03:50

Dinamik DLL

Mesaj gönderen morphine39 » 22 Eki 2010 01:51

Arkadaşlar herkese merhaba

Yeni bir projeye başlıycam ve bu sebeple bazı araştırmalar yapıyorum. Konuyu daha rahat anlatabilmem için örnekle açıklayacağım

Photoshop u açtığımızda Bazı dll ler yükleniyor ve bu dll ler ana exe üzerinde bazı yerlere kendini menü yada buton olarak koyuyor..

Benim delphi de yapmak istediğim de bu..
Ben DLL klasörünün içine DLL yi atıcam ve bu DLL içinde yazdığım prosedür ( örn : procedure FormaYerles ) sayesinde form üzerinde menüye yada herhangi bir yere butonu çizdirmek ve işlevsel hale getirmek istiyorum..


Konu ile ilgili vereceğiniz fikir, adres, bilgi, herşeye açığım..

İyi Çalışmalar

Kullanıcı avatarı
vkamadan
Kıdemli Üye
Mesajlar: 1935
Kayıt: 17 Mar 2004 03:52
Konum: Adapazarı
İletişim:

Re: Dinamik DLL

Mesaj gönderen vkamadan » 23 Eki 2010 01:29

Merhabalar ,
biraz yüzeysel olacak fakat araştırma yönünüzü değiştireceğini düşünüyorum ,
Bahsetmiş olduğunuz yapıda uygulamalar için Delphi hali hazırda Borland Package Library (BPL) yapılarını sunar, DLL gibi düşünebilirsiniz BPL in bence en güzel özelliği BPL içindeki sınıflarıda projenizde kullanabilirsiniz araştırmanızın anahtar kelimeleri Delphi Add-On + BPL olmalıdır düşüncesindeyim. Delphi ile modüler uygulama geliştirmek istiyorsanız ve modülleriniz sadece Delphi projelerinden load edilecekse hiç düşünmeden DLL kullanımı aklınızdan çıkartın ve BPL e yönelin, çünkü BPL tam olarak bu iş için yapılmıştır.

İyi çalışmalar dilerim.
Volkan KAMADAN
www.polisoft.com.tr

Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4731
Kayıt: 09 Ara 2003 08:13
Konum: Ankara
İletişim:

Re: Dinamik DLL

Mesaj gönderen mrmarman » 23 Eki 2010 04:48

Merhaba.

Bunu yapmadan önce DLL halinde ekleyeceğiniz fonksiyonların daha önceden belirleyeceğiniz bir ya da birden farklı yapıda veri alarak, sonucu aynı şekilde daha önce bildiğiniz türde sonuç verecek şekilde değerlendirerek planlamalısınız.

Örneğin, Photoshop pluginleri daima bir image nesnesini seçilmiş alan bilgisiyle birlikte alır, sonrada üzerinde yapılan işlemden sonra uygulanan ürün resmi geri iade eder. Siz bundan farklı olarak kendi projenizde olmayan yeni bir özelliği kazandırmak istiyorsanız olmayan özelliğin benzer farklı hallerinin yazılımda önceden planlayarak tanınmasını sağlamanız gerekecektir.

GEriye kalan kısım bir klasördeki DLL'leri bulup, bunları bir menüye eklemek ve ardından da kullanıcı tarafından bunlardan birisini seçtiğinde çalıştırmak işlemi oldukça basit bir işlemdir. Aşağıda örneğini verdim.

Dosyalar:
Ana Proje :
AnaProje.rar
Ana Proje (PlugIn kabul edecek) içinde iki plugin dahil
(244.3 KiB) 153 kere indirildi
DLL (iki adet) :
PlugInSRC.rar
Ekli PlugIN'lerin (PlugIn klasöründekiler) kaynak kodları
(83.74 KiB) 136 kere indirildi
Ana Proje :
Bir TMainMenu bulunan Form'da "miPlugIn" adındaki menü başlığına, yazılım ile aynı klasördeki PlugIn klasöründe bulunan DLL dosyaları eklenir. Eklenirken de her bir DLL dosyasından hangi fonksiyonu kullanacağımızı içeren bilgi çekilir.

"a" ve "b" 5 ve 6 olan ikin değişken olsun. PlugIN klasöründe bulunacak DLL'lerin her birisinden beklenen a ve b değerini alabileceği birer parametre ile sonucu yerleştireceği Variable Sonuc değişkeni.

EK: DLL içinden fonksiyonu sorgulayarak iki noktaya hizmet edildi. Birincisi DLL'nin sizi yazılımınıza uygun bir DLL olup, yabancı bir DLL kopyalanırsa hesaba katılmasının önüne geçildi. İkincisi de DLL isimleri değişebilir ama içindeki fonksiyonu çektiğimizden bu sorun doğurmayacaktır.

Kod: Tümünü seç

Function DLL_Listesi( Yol : String; VAR Liste:TStringList ) : Boolean;
{ RESET Attribute         = 128
  faArchive               =  32
  faReadOnly              =   1
  faHidden                =   2
  faSysFile               =   4
  faDirectory             =  16 }
Var
  DizinKaydi  : TSearchRec;
  DosyaAttrib : Integer;
begin
  DosyaAttrib := 167;
  Liste.Clear;
    Try
      If FindFirst( Yol + '\*.DLL', DosyaAttrib, DizinKaydi) = 0 then // 0 ise ok aksi WinErr
      begin
        If ( DizinKaydi.Attr AND DosyaAttrib ) = DizinKaydi.Attr
        then Liste.Add( Yol + '\' + DizinKaydi.Name ); // İlk Bulunan

        While FindNext(DizinKaydi) = 0 do
        begin
          If ( DizinKaydi.Attr AND DosyaAttrib ) = DizinKaydi.Attr
          then Liste.Add( Yol + '\' + DizinKaydi.Name ); // Sonraki Bulunan(lar)
        end;
        FindClose(DizinKaydi);
      end;
      Result := True;
    except
      Result := False;
    end;
end;

procedure TForm1.FormShow(Sender: TObject);
type
  TDLLParametre = function(VAR Param: ShortString): Boolean;
Var
  Liste : TStringList;
  mi    : TMenuItem;
  i     : Integer;
  hDLL  : THandle;
  tFunc : TDLLParametre;
  buffer: array [0..144] of Char;
  GelenParametre : ShortString;
begin
  Liste := TStringList.Create;
  if DLL_Listesi( ExtractFilePath(Application.Exename) + 'PlugIn', Liste ) then
  begin
    for i  := 0 to Liste.Count -1 do begin
      hDLL := LoadLibrary(StrPCopy(buffer, Liste[i]));
      if hDLL <> 0 then
      begin
        try
          @tFunc := GetProcAddress(hDll, StrPCopy(buffer, 'DLLParametre'));
          if @tFunc <> nil then begin
            tFunc( GelenParametre );
            mi := TMenuItem.Create(miPlugIn);
            mi.AutoHotkeys := maManual;
            mi.Name        := Format('miPlug%.2d', [i]);
            mi.Caption     := GelenParametre;
            mi.OnClick     := PlugInSecildi;
            mi.Tag         := hDLL; // DLL'nin handle nosunu menuye not ediyoruz...
            mi.ImageIndex  := 10;
            miPlugIn.Add(mi);
          end;
        finally
        end;
      end;
    end;
  end;
end;

procedure TForm1.PlugInSecildi(Sender:TObject);
type
  TDLLFonksiyon = function(a,b : Integer; VAR Sonuc: ShortString): Boolean;
Var
  PlugAdi : String;
  a, b : Integer;
  hDLL  : THandle;
  tFunc : TDLLFonksiyon;
  buffer: array [0..144] of Char;
  c     : ShortString;
begin
  a := 5;
  b := 6;
  PlugAdi := StringReplace( tMenuItem(Sender).Caption, '&', '', [rfReplaceAll] );
  hDLL    := tMenuItem(Sender).Tag;
  @tFunc  := GetProcAddress(hDll, StrPCopy(buffer, PlugAdi));
  if @tFunc <> nil then
  begin
    try
      tFunc( a,b,c );
    finally
    end;
  end;
  ShowMessageFmt('(%s) a=%d ile b=%d Sonuç = %s', [PlugAdi, a,b,c]);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
Var
  i    : Integer;
  hDLL : THandle;
begin
  for i := 0 to miPlugIn.Count - 1 do
  begin
    hDLL := TMenuItem(miPlugIn[i]).Tag;
    FreeLibrary(hDLL);
  end;
    
end;

DLL dosyası (a) : a ve b değerlerini çarparak sonucu döndürür.

Kod: Tümünü seç

  function DLLParametre( Var Param:ShortString ):Boolean;
  begin
    Param  := 'DLL_a_carpi_b';
    Result := True;
  end;

  function DLL_a_carpi_b( a,b:Integer; Var Sonuc:ShortString ):Boolean;
  begin
    Sonuc  := IntToStr(a * b);
    Result := True;
  end;

  Exports
    DLLParametre,
    DLL_a_carpi_b;
DLL dosyası (b) : a ve b değerlerini toplayarak sonucu döndürür.

Kod: Tümünü seç

  function DLLParametre( Var Param:ShortString ):Boolean;
  begin
    Param  := 'DLL_a_arti_b';
    Result := True;
  end;

  function DLL_a_arti_b( a,b:Integer; Var Sonuc:ShortString ):Boolean;
  begin
    Sonuc  := IntToStr(a + b);
    Result := True;
  end;

  Exports
    DLLParametre,
    DLL_a_arti_b;
Resim Resim

Cevapla