Picproje Elektronik Sitesi

PROGRAMLAMA DİLLERİ => Delphi => Konuyu başlatan: z - 09 Nisan 2010, 21:27:37

Başlık: Dll uygulaması ile ilgili
Gönderen: z - 09 Nisan 2010, 21:27:37
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?


Başlık: Ynt: Dll uygulaması ile ilgili
Gönderen: z - 09 Nisan 2010, 21:47:33
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?

Başlık: Ynt: Dll uygulaması ile ilgili
Gönderen: hasangurlek - 09 Nisan 2010, 21:55:13
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 ?
Başlık: Ynt: Dll uygulaması ile ilgili
Gönderen: z - 09 Nisan 2010, 22:08:44
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?

Başlık: Ynt: Dll uygulaması ile ilgili
Gönderen: z - 09 Nisan 2010, 22:28:44
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?
Başlık: Ynt: Dll uygulaması ile ilgili
Gönderen: Klein - 10 Nisan 2010, 10:56:29
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.
Başlık: Ynt: Dll uygulaması ile ilgili
Gönderen: hasangurlek - 10 Nisan 2010, 11:17:47
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.
Başlık: Ynt: Dll uygulaması ile ilgili
Gönderen: 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.

Ö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.
Başlık: Ynt: Dll uygulaması ile ilgili
Gönderen: hasangurlek - 10 Nisan 2010, 11:45:49
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.
Başlık: Ynt: Dll uygulaması ile ilgili
Gönderen: orhanc - 10 Nisan 2010, 11:58:07
Bir göz atın

http://delphi.about.com/od/objectpascalide/a/dlldelphi.htm (http://delphi.about.com/od/objectpascalide/a/dlldelphi.htm)
Başlık: Ynt: Dll uygulaması ile ilgili
Gönderen: Klein - 10 Nisan 2010, 12:11:28

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.
Başlık: Ynt: Dll uygulaması ile ilgili
Gönderen: z - 10 Nisan 2010, 17:19:11
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.
Başlık: Ynt: Dll uygulaması ile ilgili
Gönderen: orhanc - 11 Nisan 2010, 03:51:08
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. 
Başlık: Ynt: Dll uygulaması ile ilgili
Gönderen: z - 11 Nisan 2010, 15:20:12
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?
Başlık: Ynt: Dll uygulaması ile ilgili
Gönderen: Klein - 11 Nisan 2010, 16:06:18
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.
Başlık: Ynt: Dll uygulaması ile ilgili
Gönderen: Klein - 11 Nisan 2010, 16:17:07
Hocam sanırım sorun Delphinin  string formatı ile Windows'un string formatı arasındaki uyumsuzluktan kaynaklanıyor. Delphide metnin ilk baytı  metin uzunluğunu veriyor , windows'ta  ise bildiğimiz sıfır sonlu katar sistemi kullanılıyor.

Sorunu çözmek için "string" yerine  , windows ile uyumlu tip olan "pchar" tipini kullanmalısınız.

Ama hatanın metnini değil de  kodunu gönderip bunu program içerisinde metne çevirme yöntemini  neden kullanmadığınızı da merak ettim doğrusu.


function returnstring_DLL_Test(a:integer ; b:integer ):pchar;
var x:integer;
Begin
    x:= a+b;
    result:=pchar(inttostr(x));
End;

Başlık: Ynt: Dll uygulaması ile ilgili
Gönderen: z - 11 Nisan 2010, 16:31:06
Kodlama yontemini,  program kodlarina bakarken bu ne hatasiymis diye dusunmek gerektirdigi icin
sevmiyorum. Ancak isin icinden cikamadim ve mecburen dediginiz gibi her hataya bir kod verip karsi tarafta buna karsilik
aciklama yapacagim.
Başlık: Ynt: Dll uygulaması ile ilgili
Gönderen: z - 11 Nisan 2010, 16:59:42
Global alanda degiskenleri tanimlarken

var
Hata: Array [0..30] of string;

Seklinde tanimlama yaptigimizda

Hata[0]:='Ok'
Hata[1]:='xxxx'
Hata[2]:='yyyy'
Hata[3]:='zzzz'
....
....

Seklinde deger atamasini  kod isletmeden yapabilirmiyim?   (a:integer=1; da oldugu gibi)

Bu islemi degisken degilde const nasil yaparim?
Başlık: Ynt: Dll uygulaması ile ilgili
Gönderen: Klein - 11 Nisan 2010, 18:40:15
const errmsg:array[0..2] of string =('ahmet','mehmet','hasan');
Başlık: Ynt: Dll uygulaması ile ilgili
Gönderen: orhanc - 11 Nisan 2010, 20:30:20
const

   Days : array[0..6] of string =  (  'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'  ) ;
Başlık: Ynt: Dll uygulaması ile ilgili
Gönderen: Klein - 11 Nisan 2010, 20:47:53
const renkler : array[0..2] of string =('kırmızı','mavi','yeşil');

şeklinde de olabilir.

veya

const aylar : array[0..2] of string =( 'ocak' , 'şubat' , 'mart' );

şeklinde farklı bir düzenleme de getirilebilir.
Başlık: Ynt: Dll uygulaması ile ilgili
Gönderen: XOR - 12 Nisan 2010, 09:59:15
Delphi'de (en azından CodeGear 2007'de) Yeni bir dll projesi açtığınızda proje kodunun tepesinde aşağıdaki comment yer alır.
Özetle WideString kullanmak istiyorsanız dll'inizi BORLNDMM.DLL ile birlikte dağıtmanız ve buna uygun kodlama yapmanız lazım.
Bundan kaçınmak için iki yol var ya parametreleriniz ShortString yapmalısınız yada PChar kullanmalısınız.


Elinizdeki her hangi bir string'i pchar'a çevirmek de kolay PChar(s) ile (Compiler Option'larında "huge strings" işaretliyse) direk çevirebilirsiniz.
İşaretli değilse çevrimi yapmanız gereken yerde
{$H+}
PChar(s)
{$H-}
yaparsınız olur biter.

Kolay Gelsin.

{ 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. }