Dll uygulaması ile ilgili

Başlatan bunalmis, 09 Nisan 2010, 21:27:37

z

Delphide yazdığım programa ait fonksiyonlar dll içinde toplamak istiyorum. (Program bitti dll işi sonradan çıktı.)

Ancak yazdığım fonskiyonlar, işleyecekleri değerlerin bir kısmını parametre olarak bazıları da doğrudan global alandan alıyorlardı.

DLL yapısına geçince global değişkenler sorun olacak. Her dll fonksiyon çağrılışında bu parametreleri tekrar tekrar yollamak zoruma gidiyor en azından fonskiyonun kullanıldığı satırda uzun ve kafa karıştırıcı görüntü olışacak.

Bu global değişkenleri bir kereye mahsus bir fonksiyonın parametreleri olarak dll içine atsam ve ordaki global alana yerleşse, daha sonrada fonksiyonlar ihtiyaç duyduğunda dll içindeki bu global alandan alıp alıp kullansınlar dedim ve basit bir deneme yaptım. Program çalıştırıldığında hata mesajı alıyorum. (Exception Processing Message...)

Yapmayı düşündüğüm bu yapıda hata görüyormusunuz? Alternatif öneriniz varmı? Neden hata mesajı alıyorum?


Bana e^st de diyebilirsiniz.   www.cncdesigner.com

z

Bu arada yazdığım fonksiyonlar bir başka dll fonskiyonlarını da çağırıyordu. Şimdi kendi fonskiyonlarımı dll içine atınca bunlar diğer dll içinden fonskiyonları kolayca çağırabileceklermi?

Bana e^st de diyebilirsiniz.   www.cncdesigner.com

hasangurlek

Delphi7 de varmı bilmiyorum ama .nette bu iş için property kullanılabilir;

class InstanceClass
{
    private int _Instance; // Sınıf içinde kullanılan değişken
    public int Instance; // Property, dışardan _Instance değişkeninin değerini atamak veya okumak için
    {
        get 
        { 
            return _Instance; //Değişkenin değerini döndürür
        }
        set 
        {
            _Instance = value; //Değişkene yeni değeri atar
        }
    }
}


Eski yeni tüm fonksiyonları tek bir dll içine toplamanıza engel nedir ?
http://www.cyber-warrior.org, Although they like whiteness, sometimes twilight is required...  Hala evlilermi bilinmez ama kesinlikle artık uygun değiller !!!

z

#3
Dlllerden birisini çip üreticisi veriyor. (Kod hali yok)

Diğeri de kendi yazdığım fonksiyonları içerecek.

Bir diğer problem de dll içine atmak istediğim bazı fonskiyonlar form üzerinde bazı label yada editbox ların text değerlerini değiştiriyordu. Bu fonskiyonları bu halleriyle dll içine atabilecekmiyim?

Bana e^st de diyebilirsiniz.   www.cncdesigner.com

z

DLL in uses kısmına Unit1 i dahil edip

Fonksiyonlardan birisinin içine form1.caption:='AAA' gibi bir satır ekleyip dll oluşturdum.

Bir uygulama programından da bu dll in caption değiştiren fonksiyonunu çağıdırdım.

Kod hata vermeden çalıştı ancak form captionda hiç bir değişiklik yapmadı.

Sorun nedir?
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

Klein

#5
Winows'ta her pencerein ir handle numarası vardır.  tüm uygulamalar bu numara ile işlem yapar.  Sizin DLL'inize form1 var ama , çalıştırdığınız uygulamadaki form1 , o form1 değil. Ancak  programınızda DLL içerisindekiş formun create, init vs... gibi fonksiyonlarını çalıştırııp o DLL içerisinde tarif edilen formu oluşturursanız  ancak o zaman formun bir HWND  numarası olur.


Eğer DLL'e  yerleştireceğiniz fonksiyonlar form üzerindeki bazı omponentler üzerinde işlem yapıyorsa , doğrudan o komponente referans vermek zaten yanlış bir yaklaşım olur.

hasangurlek

DLL dosyaları dinamik kütüphanelerdir. Her birinin fonksiyonlarını herhangi bir kod içine import edip kullanabilirsiniz. Diğer yöntem ise loadlibrary apisi ile kütüphaneyi belleğe yükleyip getprocadress apisi ile bellek adresinden ilgili fonksiyonu çalıştırmaktır.

Ancak kütüphaneler içindeki kodlar form üzerindeki nesnelerle direk etkileşime giremez yani form üzerindeki bir nesneye müdahale edemez. Bunu yapmak için caption değiştiren fonksiyonunuz bir event yaratacak, event meydana geldiğinde çalışacak kod form class içinde olacak.

Bülent hocam epeydir delphi kullanmıyorum, makinemdede kurulu değil bunun için yine .netten örnek verdim. Kütüphane kod örneği;

Public Class InstanceClass
    Public Shared Event CaptionEvent(ByVal Caption As String)

    Public Sub ChangeCaption()
        'İŞLEMLER
        RaiseEvent CaptionEvent("New Caption")
    End Sub
End Class


Form kod örneği;

    Private Class FormX
        Private WithEvents CaptionProcesses As New InstanceClass

        Private Sub CaptionEvent(ByVal NewCaption As String)
            Me.Caption = NewCaption
        End Sub
    End Class


Bu sayede dinamik kütüphane içinde olay tetiklendiğinde kod akışı form içindeki rutine yönelip captionda değişiklik yapabilir.
http://www.cyber-warrior.org, Although they like whiteness, sometimes twilight is required...  Hala evlilermi bilinmez ama kesinlikle artık uygun değiller !!!

Klein

#7
Bu işin bence doğru yolu
üzerinde işlem yapılacak nesneyi , DLL içerisindeki fonksiyona parametre olarak geçmektir.

Örneğin

DLL örneği
library DllTest;
uses
  SysUtils,
  Classes,stdctrls;

{$R *.res}
procedure Label_DLL_Test(TargetLabel:Tlabel ; captiondata:string);
Begin
    targetlabel.Caption:=captiondata;
End;
exports
  Label_DLL_Test;

begin
end.



Bu da DLL içerisindeki fonksiyonu çağırmak ve formumuz üzerindeki Label nesnesinin başlığını değiştirmek için kullanacağımız yöntem

unit unt_DllTestApp;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,stdctrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

procedure Label_DLL_Test(TargetLabel:Tlabel ; captiondata:string); external 'dlltest.dll';

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
   Label_DLL_Test(label1,'DLL den label caption degistirme');
end;

end.

hasangurlek

Alıntı yapılan: Klein - 10 Nisan 2010, 11:28:14
Bu işin bence doğru yolu
üzerinde işlem yapılacak nesneyi , DLL içerisindeki fonksiyona parametre olarak geçmektir.

%100 haklısın, eğer kod akışı içinde caption değiştirilmek istenirse caption değeri için dll fonksiyonunun dönüşü kullanılabilir.

Benim verdiğim event örneği, Bülent hocanın epeydir uğraştığı ve baya büyüdüğünü düşündüğüm proje içerisinde kullanışlı olabileceği içindi. Sanırım hocam formdaki değerleri belli olaylar sonucunda değiştirerek arka planda yürüyen işler hakkında kullanıcıya bilgi veriyor. Eventlerde bu işlemleri otomatiğe bağlar diye düşünmüştüm.
http://www.cyber-warrior.org, Although they like whiteness, sometimes twilight is required...  Hala evlilermi bilinmez ama kesinlikle artık uygun değiller !!!

orhanc

i'm doing nothing... Giddy Up  http://www.drorhan.com

Klein


Alıntı yapılan: hasangurlek - 10 Nisan 2010, 11:45:49
%100 haklısın, eğer kod akışı içinde caption değiştirilmek istenirse caption değeri için dll fonksiyonunun dönüşü kullanılabilir.

DLL'in dönüşüne bile gerek yok. doğrudan form da parametre olarak geçilebilir.

Ama illa ki form içerisine  nesneleri doğrudan yerleştirmek gerekirse , RESOURCE DLL'leri var. delphi buna da izin veriyor. Ama ben hiç bu tip bir DLL ile çalışmadım.


Bu sefer   rutinimiz a ile b yi toplayıp , sonucu hedef nesnenin başlığına yazıyor.
library DllTest;
uses
  SysUtils,
  Classes,stdctrls,forms;

{$R *.res}
procedure Label_DLL_Test(TargetLabel:Tlabel ; captiondata:string);
Begin
    targetlabel.Caption:=captiondata;
End;

procedure Object_DLL_Test(TargetObject:TObject ; a:integer ; b:integer);
var x:integer;
Begin
    x:= a+b;
    tform(targetobject).Caption:=inttostr(x);
End;

exports
  Object_DLL_Test,
  Label_DLL_Test;

begin
end.


unit unt_DllTestApp;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,stdctrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

procedure Label_DLL_Test(TargetLabel:Tlabel ; captiondata:string); external 'dlltest.dll';
procedure Object_DLL_Test(TargetObject:TObject ; a:integer ; b:integer); external 'dlltest.dll';

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
   Label_DLL_Test(label1,'DLL den label caption degistirme');
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  object_DLL_Test(form1,60,30);
end;

end.

z

Form1 fonskiyonlarinin bir kismini DLL yaptim ve soyle bir sorunla daha karsilastim.

Form kisminda kalan bazi fonskiyonlarin da dll icindeki fonksiyonlarca cagrilmasi gerekiyor.

Ornegin hata mesajlarinin gosteren fonskiyonum dll disinda kaldi. Dll deki bir fonskiyon bu fonskiyonu cagirabilirmi?

En basta dll kullanaracagimi ongorseydim isim kolay olacakti. Bitmis programin fonskiyonlarini dll yapisina cevirmeye kalktigimda
bir suru takla atmam gerekiyor.

Aslinda en iyisi biraz zaman ayririp yeni bastan  yazmak.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

orhanc

DLL'i kullanan başak programlarınız var mı ? DLL yerine bi tane unit tanımlayıp ortak kullanılan fonksiyon ve prosedürleri oraya yazabilirsiniz. DLL kullanarak delphinin tek exe ile çalışma mantığını da kırmış oluyorsunuz. 
i'm doing nothing... Giddy Up  http://www.drorhan.com

z

DLL fonsksiyonlarin urettigi degerleri structure uzerinden ana programa donduruyorum.

Structure in elemanlarindan birisi de string tanimli Hata mesaji degiskeni.

Ancak bu degisken sorun yaratiyor.

Soyleki;

Eger structure dan string tanimli degiskeni kaldirirsam (hem ana programdan hemde DLL den) fonskiyonlar sorunsuz calisiyor.
Eger string tanimli degiskeni devreye sokarsam exeption hatalari cikiyor.

Sorun nedir?

String degiskenleri dll uzerinden yollamanin bir sakincasi varmi?
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

Klein

DLL fonksiyon geri dönüşlerinde string kullanılırsa delphi bir exception üretiyor.  Ama buna karşın görevi yerine getiriyor.  Geri dönüş olarak string kullanmayı tercih etmediğim için sebebi üzerine araştırma yapmadım. 
Ancak çok gerekli olursa try...except bloğu kullanarak  hatayı kendim yöneterek , yani hatayı görmezden gelerek sorunu aşardım.
Ancak  hata kodu yerine , doğrudan hataya ilişkin metni  geri döndürmenin de efektif bir yöntem olduğu kanaatinde değilim.