Aracılığıyla paylaş


__declspec(dllimport) Kullanarak İşlev Çağrılarını İçeri Aktarma

Aşağıdaki kod örneği _declspec(dllimport)'in DLL'den uygulamaya işlev içe aktarma için nasıl kullanılacağını gösterir. func1'in main işlevi barındıran .exe dosyasından ayrı bir DLL'de bulunan işlev olduğunu var sayın.

__declspec(dllimport) olmadan, şu kod verildiğinde:

int main(void) 
{
   func1();
}

derleyici aşağıdaki koda benzer bir kod oluşturur:

call func1

ve bağlayıcı çağrıyı aşağıdakine benzer bir şeye çevirir:

call 0x4000000         ; The address of 'func1'.

Eğer func1 başka bir DLL'de bulunuyorsa, bağlayıcı bunu doğrudan çözümleyemez çünkü, func1 adresinin ne olduğunu bilmesinin bir yolu yoktur. 16 bit ortamda, bağlayıcı bu kod adresini yükleyicinin çalışma zamanında doğru adresle düzeltme ekini uygulayacağı şekilde .exe dosyasında bir listeye ekler. 32 bit ve 64 bit ortamlarda, bağlayıcı adresi bilen dönüştürücü oluşturur. 32 bit ortamda dönüştürücü aşağıdakine benzer:

0x40000000:    jmp DWORD PTR __imp_func1

Burada imp_func1, .exe dosyasının içe aktarma adres tablosundaki func1 yuvasının adresidir. Böylece bütün adresler bağlayıcı tarafından bilinir. Yükleyici her şeyin doğru çalışması için sadece yükleme zamanında .exe dosyasının içe aktarma adres tablosunu güncellemelidir.

Bu nedenle, __declspec(dllimport) kullanmak daya iyidir çünkü, bağlayıcı gerekli değilse dönüştürücü oluşturmaz. Dönüştürücüler kodu daha büyük yapar (RISC sistemlerinde, bir çok yönerge olabilir) ve ön bellek başarımınızı kötüleştirir. Eğer siz derleyiciye işlevin DLL'de olduğunu söylerseniz, sizin için dolaylı bir çağrı oluşturabilir.

Böylece şimdi bu kod:

__declspec(dllimport) void func1(void);
int main(void) 
{
   func1();
}

bu yönergeyi oluşturur:

call DWORD PTR __imp_func1

Dönüştürücü ve jmp yönergesi yoktur, böylece kod daha küçük ve hızlıdır.

Diğer taraftan, DLL içinden işlev çağrıları için dolaylı çağrı kullanmak zorunda kalmak istemezsiniz. Zaten işlevin adresini biliyorsunuz. Dolaylı çağrıdan önce işlevin adresini yüklemek ve saklamak için zaman ve yer gerekli olduğundan, doğrudan çağrı daima daha hızlı ve daha küçüktür. __declspec(dllimport)'u sadece DLL işlevlerini DLL'in kendisinin dışından çağırırken kullanmak istersiniz. __declspec(dllimport)'i DLL içindeki işlevlerde o DLL'i oluştururken kullanmayınız.

Ayrıca bkz.

Kavramlar

Uygulamanın İçine Aktarma