Windows API Fonksiyon Çağırım Yöntemi

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Kullanıcı avatarı
kimimben
Üye
Mesajlar: 129
Kayıt: 28 Oca 2016 04:41
Konum: İstanbul

Windows API Fonksiyon Çağırım Yöntemi

Mesaj gönderen kimimben »

Selamınaleyküm.

TestMethod1 ve TestMethod2 içersinde kullanılan, PathFileExists Win API fonksiyonun kullanım farklılığı, avantajı, dezavantajı nedir ?

Kod: Tümünü seç

program Project2;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils,
  Winapi.Windows,
  System.StrUtils,
  Winapi.ShLwApi;

procedure TestMethod1;
var
  filePath: WideString;
  result: BOOL;
begin
  filePath := 'C:\x.txt';
  result := PathFileExists(@filePath);
  Writeln('Result:'+BoolToStr(result,true));
end;

procedure TestMethod2;
type
  TPathFileExists = function (pszPath: PWideChar): BOOL; stdcall;
var
  libFileName: WideString;
  hModule : HINST;

  PPathFileExists : TPathFileExists;
  result : BOOL;
begin
  hModule := LoadLibrary('shlwapi.dll');
  if (hModule = 0) then exit;
  PPathFileExists := GetProcAddress(hModule, 'PathFileExistsW');
  if not Assigned(PPathFileExists) then exit;
  result := PPathFileExists('C:\y.txt');
  Writeln('Result:'+BoolToStr(result,true));
  FreeLibrary(hModule);
end;

begin
  try
   TestMethod1;
   TestMethod2;
   Readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;

end.


TestMethod1 içersinde doğrudan Winapi.ShLwApi.pas içersinde tanımlı olan fonksiyonu kullanıyoruz.

Kod: Tümünü seç

function PathFileExists; external shlwapi32 name 'PathFileExistsW';
TestMethod2 içersinde ise,shlwapi.dll yükledikten sonra içersinden PathFileExistsW fonksiyonunun adresini bulup, çağırıyoruz.

Arada ne fark var ?
thelvaci
Kıdemli Üye
Mesajlar: 770
Kayıt: 11 Tem 2010 07:17
Konum: Istanbul
İletişim:

Re: Windows API Fonksiyon Çağırım Yöntemi

Mesaj gönderen thelvaci »

Aynı metodu çağırdığınıza göre arada bir fark olmayacaktır. Arada oluşabilecek tek fark, PathFileExists API'sinin tanımının yapıldığı Winapi.ShLwApi unit'ini projenize dahil etmediğinizde EXE boyutunda çok cûzi bir azalma olacaktır. Gereken DLL'i dinamik olarak yüklediğiniz de de aynı metoda erişmiş oluyorsunuz nihayetinde.

Ama nedense bana sormak istediğiniz şey başka bir şeymiş gibi geliyor.

Not: PathFileExists API'si internal olarak GetFileAttributes API'sini çağırır ve bu API'den dönen değerin INVALID_FILE_ATTRIBUTES olup olmadığını kontrol eder sadece.
ertank
Kıdemli Üye
Mesajlar: 1652
Kayıt: 12 Eyl 2015 12:45

Re: Windows API Fonksiyon Çağırım Yöntemi

Mesaj gönderen ertank »

Merhaba,

Tuğrul Bey'in cevabına ek olarak ikinci yöntem dinamik DLL yükleme ve fonksiyon mevcut mu kontrolleri sebebi ile işlemci zamanını daha çok alacaktır. Mümkün olduğunca mevcut olmayan fonksiyonlar için DLL kullanmakta fayda var. Hepimizin bildiği gibi Delphi işlemci üzerinde çalışan kod üretir. Mevcut fonksiyonlar daha hızlı çalışan uygulama oluşturacaklardır.

Diğer taraftan WideString türünü kullanmamaya çalışın. Bu değişken türü Windows işletim sistemi tarafından yönetilir ve çok fazla arkaplan işlemi (overhead) vardır. WideString özellikle COM nesneleri ile uğraşılacağı zaman kullanılması gerekli oluyor bunun dışında yerine UnicodeString veya string tercih edilebilir.

Son olarak, Tuğrul Bey'in bahsettiği EXE boyutu büyüklüğü ile ilgili aşağıdaki linkteki ücretsiz uygulamayı inceleyebilirsiniz. Release olarak derlenmiş EXE boyutunu bir miktar daha ufaltmaya yardımcı olur.
http://upx.sourceforge.net/
Artık geliştirilmesi durmuş veya çok yavaşlamış olan aşağıdaki ücretli uygulamayı da inceleyebilirsiniz. UPX'e göre daha hızlı ve daha küçük EXE üretebilir.
https://bitsum.com/pecompact/
ertank
Kıdemli Üye
Mesajlar: 1652
Kayıt: 12 Eyl 2015 12:45

Re: Windows API Fonksiyon Çağırım Yöntemi

Mesaj gönderen ertank »

Soruyu tekrar yorumladıktan sonra şöyle cevaplamakta mümkün.
Metod1 statik link şeklinde DLL bağlantısı sağlar. Delphi Winapi kodları statik şekilde tanımlanmıştır.
Metod2 dinamik link şeklinde DLL bağlantısı sağlar.

Her iki metodun kullanım avantajı farklılık gösterir. Eğer embedded gibi limitli işletim sistemleri için uygulama geliştiriyor iseniz statik bağlantı kullanmak daha avantajlı olabilir.

Detaylar ile ilgili şuraya bakabilirsiniz.
https://stackoverflow.com/questions/199 ... ic-linking

Kısa cevap olarak, üzerinde çok düşünmeden metod1 tercih edilebilir.
Kullanıcı avatarı
kimimben
Üye
Mesajlar: 129
Kayıt: 28 Oca 2016 04:41
Konum: İstanbul

Re: Windows API Fonksiyon Çağırım Yöntemi

Mesaj gönderen kimimben »

Öncelikle Tuğrul bey ve Ertan bey ilgilendiğiniz için teşekkür ederim.
Sizin düşündüğünüz açından düşünmemiştim.
thelvaci yazdı: Ama nedense bana sormak istediğiniz şey başka bir şeymiş gibi geliyor.
Evet.
ertank yazdı:üzerinde çok düşünmeden metod1 tercih edilebilir.
Biraz daha düşünmek istiyorum.
Kullanıcı avatarı
kimimben
Üye
Mesajlar: 129
Kayıt: 28 Oca 2016 04:41
Konum: İstanbul

Re: Windows API Fonksiyon Çağırım Yöntemi

Mesaj gönderen kimimben »

Aşağıda Zarko beyefendi de avantaj ve dezavantaj olarak farklıkları belirtmiş.
Static vs. Dynamic Dynamic Link Library Loading - A Comparison

ertank yazdı: Metod1 statik link şeklinde DLL bağlantısı sağlar. Delphi Winapi kodları statik şekilde tanımlanmıştır.
Static olarak external direktifi ile ilgili API fonksiyonunu tanımlamamız, program çalıştırıldığında ilgili DLL'in(görüntüde SHLWAPI.dll) "belleğe bir kez yüklemesi" ve "method binding" işleminin gerçekleştiği görülüyor.
Resim
ertank yazdı: Metod2 dinamik link şeklinde DLL bağlantısı sağlar.
Dinamik olarak yani LoadLibrary API'si ile, ilgili DLL'i "istediğimiz bir zamanda" yükleyip, çağırmak istediğimiz fonksiyon için gerekli method binding işlemini GetProcAddress yardımıyla gerçekleştiriyoruz.


Burada DLL'in yüklenme zamanı ve diğer farklılıklardan farklı olarak dikkatimi çeken diğer bir nokta;
Derleyici external direktifi ile ilgili DLL'i yükleyip, ilgili fonksiyonu adresleyip çağırabilmemizi sağlıyorken, dinamik yüklemede bu işlemi biz yapıyoruz.


Diğer bir husus yüklenme zamanı ile ilgili;
Uygulama da tanımlı ne kadar static link şeklinde fonksiyon varsa, program açılışında ilgili tüm DLL'ler belleğe yüklenmiş olacak.
Çok nadir zaman aralıklarında kullanılmak üzere, programlamak istediğimiz bir fonksiyon için, ilgili DLL'in programın her açılışında yüklenmesi ne kadar doğru olabilir. Buna güzel bir örnek ;
Plugins always call for dynamic linking.
thelvaci
Kıdemli Üye
Mesajlar: 770
Kayıt: 11 Tem 2010 07:17
Konum: Istanbul
İletişim:

Re: Windows API Fonksiyon Çağırım Yöntemi

Mesaj gönderen thelvaci »

kimimben yazdı:Aşağıda Zarko beyefendi de avantaj ve dezavantaj olarak farklıkları belirtmiş.
Static vs. Dynamic Dynamic Link Library Loading - A Comparison

ertank yazdı: Metod1 statik link şeklinde DLL bağlantısı sağlar. Delphi Winapi kodları statik şekilde tanımlanmıştır.
Static olarak external direktifi ile ilgili API fonksiyonunu tanımlamamız, program çalıştırıldığında ilgili DLL'in(görüntüde SHLWAPI.dll) "belleğe bir kez yüklemesi" ve "method binding" işleminin gerçekleştiği görülüyor.
Resim
ertank yazdı: Metod2 dinamik link şeklinde DLL bağlantısı sağlar.
Dinamik olarak yani LoadLibrary API'si ile, ilgili DLL'i "istediğimiz bir zamanda" yükleyip, çağırmak istediğimiz fonksiyon için gerekli method binding işlemini GetProcAddress yardımıyla gerçekleştiriyoruz.


Burada DLL'in yüklenme zamanı ve diğer farklılıklardan farklı olarak dikkatimi çeken diğer bir nokta;
Derleyici external direktifi ile ilgili DLL'i yükleyip, ilgili fonksiyonu adresleyip çağırabilmemizi sağlıyorken, dinamik yüklemede bu işlemi biz yapıyoruz.


Diğer bir husus yüklenme zamanı ile ilgili;
Uygulama da tanımlı ne kadar static link şeklinde fonksiyon varsa, program açılışında ilgili tüm DLL'ler belleğe yüklenmiş olacak.
Çok nadir zaman aralıklarında kullanılmak üzere, programlamak istediğimiz bir fonksiyon için, ilgili DLL'in programın her açılışında yüklenmesi ne kadar doğru olabilir. Buna güzel bir örnek ;
Plugins always call for dynamic linking.
Küçük bir düzeltme yapayım, derleyici DLL'in yüklenmesini sağlamıyor; sadece ilgili DLL'in PE/PE+ dosyasında yerini ayarlıyor-ki Windows Loader PE/PE+ dosyasını okur iken ilgili DLL'i bulabilsin ve yükleyebilsin. Ayrıca dikkatini başka bir şey çekmedi mi güzel kardeşim ? Mesela benim bir önceki mesajımdaki Not kısmı gibi ;)
Kullanıcı avatarı
kimimben
Üye
Mesajlar: 129
Kayıt: 28 Oca 2016 04:41
Konum: İstanbul

Re: Windows API Fonksiyon Çağırım Yöntemi

Mesaj gönderen kimimben »

thelvaci yazdı: Küçük bir düzeltme yapayım, derleyici DLL'in yüklenmesini sağlamıyor
Hangi kafayla yazdıysam, salakça bir cümle olmuş.Kabul ediyorum.
Nerde görülmüş derleyicinin DLL'i yüklediği :D
thelvaci yazdı: Not: PathFileExists API'si internal olarak GetFileAttributes API'sini çağırır
Cümlede geçen "internal olarak" ibaresi dikkatimi çekti.Merak ettim.Fakat anlamını bilmediğim için umursamadım.
Halbu ki anlamını bilmediğim birşeyi araştırmam gerekirdi.
Onu bir araştırayım.Geri döneceğim.
Kullanıcı avatarı
kimimben
Üye
Mesajlar: 129
Kayıt: 28 Oca 2016 04:41
Konum: İstanbul

Re: Windows API Fonksiyon Çağırım Yöntemi

Mesaj gönderen kimimben »

http://zorro-project.com/manual/en/litec_api.htm
DLLs can contain two kinds of functions: exported and internal. The exported functions can be called by other modules. Internal functions can only be called from within the DLL where they are defined.
DLL içersinde ki fonksiyon türleri exported ve internal türünde olabiliyormuş.Ve exported türünde ki fonksiyonları diğer modüllerden çağırmak mümkün iken, internal fonksiyonların sadece tanımlı oldukları DLL içersinde çağırılabiliniyormuş.

Bunun dışında Calling Internal APIs dokümanında internal windows api'ler ile ilgili bilgiler var.Fakat olayı henüz anlayamadım.
thelvaci yazdı:Not: PathFileExists API'si internal olarak GetFileAttributes API'sini çağırır ve bu API'den dönen değerin INVALID_FILE_ATTRIBUTES olup olmadığını kontrol eder sadece.
Tekrar düşünecek olursak;
Shlwapi.dll içersinde ki PathFileExists fonksiyonu, Kernel32.dll içersinde ki GetFileAttributes fonksiyonunu nasıl çağırıyor mu ?
Yoksa yanlış sularda mı geziyorum :D
thelvaci
Kıdemli Üye
Mesajlar: 770
Kayıt: 11 Tem 2010 07:17
Konum: Istanbul
İletişim:

Re: Windows API Fonksiyon Çağırım Yöntemi

Mesaj gönderen thelvaci »

DLL, EXE, Device Driver(.sys) vb. bunların hepsi PE/PE+ 'dır ve hem Import hem de Export imkanları vardır. Benim internal'dan kastım sizin bahsettiğiniz değil aslında. Şunu demek istemiştim kısaca; Shlwapi.dll içersindeki PathFileExists API'si kendi içinde Kernel32.dll içersindeki GetFileAttributes API'sini çağırıyor.

Peki bunu ben nereden/nasıl biliyorum ;)
Kullanıcı avatarı
kimimben
Üye
Mesajlar: 129
Kayıt: 28 Oca 2016 04:41
Konum: İstanbul

Re: Windows API Fonksiyon Çağırım Yöntemi

Mesaj gönderen kimimben »

thelvaci yazdı:Peki bunu ben nereden/nasıl biliyorum ;)
Bende aynı şekilde nerden bildiğinizi düşünüp, how call win internal api şeklinde bir arama yaptıktan sonra Process Monitor'e ulaştım.

Sonra uygulamadan PathFileExists api'sini çağırdım.
Resim
thelvaci
Kıdemli Üye
Mesajlar: 770
Kayıt: 11 Tem 2010 07:17
Konum: Istanbul
İletişim:

Re: Windows API Fonksiyon Çağırım Yöntemi

Mesaj gönderen thelvaci »

kimimben yazdı:
thelvaci yazdı:Peki bunu ben nereden/nasıl biliyorum ;)
Bende aynı şekilde nerden bildiğinizi düşünüp, how call win internal api şeklinde bir arama yaptıktan sonra Process Monitor'e ulaştım.

Sonra uygulamadan PathFileExists api'sini çağırdım.
Resim
Evet gayet güzel ama Process Monitor, Process Hacker vb. pek detaylı malümat vermez sana. Daha detaylısını api monitör'ler verir. Peki diyelim ki ben de senin izlediğin yolları takip ederek hangi api'nin çağrıldığını buldum. Peki ilgili API'nin içinde (PathFileExists) GetFileAttributes API'sinden dönen değerin INVALID_FILE_ATTRIBUTES ile kıyaslandığını nereden biliyor olabilirim ;)
Kullanıcı avatarı
kimimben
Üye
Mesajlar: 129
Kayıt: 28 Oca 2016 04:41
Konum: İstanbul

Re: Windows API Fonksiyon Çağırım Yöntemi

Mesaj gönderen kimimben »

Tekrar Merhaba
Evet kıyaslama yaptığını anlamak için, PathFileExists fonksiyonun gövdesinde yazan kodu görebiliyor olmak gerekir diye düşünüyorum.
Peki biz göremezken, siz nasıl görebiliyorsunuz...
Bir ipucu verebilir misiniz ? Misal API monitör ile görüntülüyorum gibi...
Doğrudan söylemeyip, ipucu verirseniz daha makbule geçer :D
thelvaci
Kıdemli Üye
Mesajlar: 770
Kayıt: 11 Tem 2010 07:17
Konum: Istanbul
İletişim:

Re: Windows API Fonksiyon Çağırım Yöntemi

Mesaj gönderen thelvaci »

kimimben yazdı:Tekrar Merhaba
Evet kıyaslama yaptığını anlamak için, PathFileExists fonksiyonun gövdesinde yazan kodu görebiliyor olmak gerekir diye düşünüyorum.
Peki biz göremezken, siz nasıl görebiliyorsunuz...
Bir ipucu verebilir misiniz ? Misal API monitör ile görüntülüyorum gibi...
Doğrudan söylemeyip, ipucu verirseniz daha makbule geçer :D
İpucu istediğiniz için şöyle bir yanıt verebilirim:

"Açık kaynak kodlu Windows çekirdeği ile uyumlu bir işletim sisteminin kaynak kodlarını inceliyorum fırsat buldukça; siz de aynı yolu izleyebilirsiniz."
Kullanıcı avatarı
kimimben
Üye
Mesajlar: 129
Kayıt: 28 Oca 2016 04:41
Konum: İstanbul

Re: Windows API Fonksiyon Çağırım Yöntemi

Mesaj gönderen kimimben »

thelvaci yazdı:"Açık kaynak kodlu Windows çekirdeği ile uyumlu bir işletim sisteminin kaynak kodlarını inceliyorum fırsat buldukça; siz de aynı yolu izleyebilirsiniz."
Cevap için teşekkürler Tuğrul Bey.
İpucu mesajı alınmıştır.Araştıracağım.
Cevapla