BILGI: _declspec(dllimport) & _declspec(dllexport) kod içinde kullanma

ÖNEMLİ: Bu makale, bir kişi tarafından çevrilmek yerine, Microsoft makine-çevirisi yazılımı ile çevrilmiştir. Microsoft size hem kişiler tarafından çevrilmiş, hem de makine-çevrisi ile çevrilmiş makaleler sunar. Böylelikle, bilgi bankamızdaki tüm makalelere, kendi dilinizde ulaşmış olursunuz. Bununla birlikte, makine tarafından çevrilmiş makaleler mükemmel değildir. Bir yabancının sizin dilinizde konuşurken yapabileceği hatalar gibi, makale; kelime dağarcığı, söz dizim kuralları veya dil bilgisi açısından yanlışlar içerebilir. Microsoft, içeriğin yanlış çevrimi veya onun müşteri tarafından kullanımından doğan; kusur, hata veya zarardan sorumlu değildir. Microsoft ayrıca makine çevirisi yazılımını sıkça güncellemektedir.

Makalenin İngilizcesi aşağıdaki gibidir:132044
Bu makale arşivlenmiştir. "Olduğu gibi" sunulmaktadır ve bundan sonra güncelleştirilmeyecektir.
Özet
Bu makalede, Microsoft Bilgi Bankası'ndaki aşağıdaki makalede anlatılan bilgiler tamamlar:
107501BILGI: __declspec, Visual C++ 32-bit olarak değiştirilen __export
Bu makalede, olumlu ve _declspec(dllimport) ve _declspec(dllexport) uygulamanızda kullanmanın mechanics anlatılır.
Daha fazla bilgi
Visual C++'ın 32-bit sürümü _declspec(dllimport) _declspec(dllexport) önceden Visual C++ 16-bit sürümlerinde kullanılan __export anahtar sözcüğü değiştirmek için kullanır.

Doğru derlemeye _declspec(dllimport) kodunuz için kullanmak gerekmez, ancak yapmak, böylece daha iyi kod üretmede derleyici sağlar. Derleyici, emin olmak için bir işlev veya bir DLL dosyasında bulunup bildiğinden, daha iyi kod oluşturmak, derleyici zamanki yönlendirme düzeyi Atla kodlarını oluşturabilir, böylece bir işlev çağrısında bir DLL sınırı aşıldı bulunması mümkün olur.

Uygun .def dosyası EXPORTS bölümle, _declspec(dllexport) gerekli değildir. _declspec(dllexport), bir .def dosyası kullanmadan bir .exe veya .dll işlevleri vermek için kolay bir yol sağlamak için eklenmiştir.

Bu makalenin geri kalanında, bu sorunların oldukça düşük düzeyli, kapsamlı bir tartışma sağlar.

Win32 taşınabilir yürütülebilir dosyası biçimini alır Düzeltilecek işlemdeki gereken sayfaların sayısını en aza indirmek için tasarlanmıştır. Bunu yapmak için <a0></a0>, herhangi bir programı için tüm alma adresleri Al adres tablosu olarak adlandırılan tek bir yerde yerleştirir. Bu, yükleyici, yalnızca bir veya iki sayfa bu alır erişirken değiştirmeye olanak sağlar.

Işlev çağrıları için _declspec(DllImport) kullanma

Aşağıdaki kod örneği, func1 main() işlevini içeren .exe dosyasından ayrı bir DLL bulunan bir işlevdir varsayalım.

Bu kod _declspec(DllImport), verilen:
void main(void) {    func1();}				
şuna benzer bir kod derleyici oluşturur:
call func1				
ve şöyle bir şey çağrıda linker çevirir:
call 0x4000000         ; The address of 'func1'.				
başka bir DLL dosyasında 'func1' var, 'func1' nin adresini nedir bilmenin bir yolu yoktur çünkü linker bunu doğrudan çözmek başlatamıyor. 16-Bit ortamlarda, the linker bir listede, yükleyiciyi çalışma zamanında doğru adresle düzeltme eki .exe bu kod adresi ekler. 32 Bit ortamlarda, kendisi için bu adresi biliyor bir thunk the linker oluşturur. The thunk şöyle görünür:
   0x40000000:    jmp DWORD PTR __imp_func1				
burada __imp_func1 .exe dosyasının <a1>alma</a1> adresi tablosundaki func1'ın yuvayı adresidir. Tüm adresleri böylece için linker olarak bilinir. Yükleyiciyi yalnızca .exe dosya alma adresi tablosu, her şey düzgün çalışması için yükleme zamanında güncelleştirmek de vardır.

The linker bir thunk oluşturmuyor için yoksa, daha iyi olduğu için bu nedenle _declspec(dllimport) kullanarak daha uygundur. Kod thunks büyütmek (rısc TABANLı sistemlerde, onu birkaç yönergeleri olabilir) ve kendi önbellek performans düşebilir. Derleyici bir DLL'dir bir işlev bildirmek, onu dolaylı bir çağrı sizin için oluşturabilir.

Böylece artık bu kod:
__declspec(dllimport) void func1(void);void main(void) {    func1();}				
bu yönergesi oluşturur:
call DWORD PTR __imp_func1				
yok yok thunk ve hiçbir jmp yönerge; bu nedenle, daha küçük ve hızlı kodudur.

Öte yandan, bir DLL içinde işlev çağrıları için dolaylı bir çağrı kullanmak zorunda istemiyorum. Bir işlevin adresi zaten biliyor. Zaman ve yer yüklemek ve doğrudan bir aramayı her zaman daha hızlı ve daha küçük olacak şekilde dolaylı bir çağrı önce işlevin adresi depolamak için gereklidir. Yalnızca __declspec(dllimport) DLL işlevleri dışındaki ararken kullanmak istediğiniz DLL kendisi. __Declspec(DllImport) içinde bir DLL işlevi, bu DLL oluştururken kullanmayın.

_Declspec(dllexport) kullanma

Microsoft, derleyici verme adları otomatik olarak oluşturmak ve bunları bir .LIB dosyasında izin vermek için 16 bit Derleyicisi sürüm __export kullanıma sunmuştur. Bir DLL ile bağlamak için bu .LIB dosya sonra yalnızca statik bir .LIB gibi kullanılabilir.

Microsoft, bu kullanışlı devam etmek için __declspec(dllexport) eklendi. Amacı; bu nedenle, bir .def dosyası gerekmeyen nesne dosyaya verme yönergesini eklemektir.

Vermek istediğiniz, C++ işlev adları donatılmış bu kullanışlı en belirgin olur. Verilen bir fonksiyonun adını, derleyici sürümleri arasında değişebilir, dolayısıyla ad düzenleme için standart belirtim yoktur. _Declspec(dllexport) kullanırsanız, DLL ve bağımlı .exe dosyaları recompiling adlandırma kuralına değişiklikleri yalnızca hesap için gereklidir.

Sıra sayılarını, NONAME veya PRIVATE, bir .def dosyası yalnızca yapılabilir ve bir .def dosyası olmadan bu öznitelikleri belirtmek için bir yol gibi birçok yönergeleri verin. Ancak, bir .def dosyası kullanarak ek olarak _declspec(dllexport) kullanarak derleme hataları neden olmaz.

Başvuru olarak Win32 WINBASE.H üstbilgi dosyası aracılığıyla arayın. Bu, tercih edilen __declspec(dllexport) ve __declspec(dllimport) kullanım örnekleri içerir.

_Declspec(dllexport) _declspec(dllimport) üzerinde veri ile

Söz konusu olduğunda, _declspec(dllimport) kullanarak bir yönlendirme katmanı silen bir kullanışlı maddenin veridir. Bir DLL dosyasından veri aldığınızda, hala alma adresi tablosu gitmek zorunda. Win32 gün _declspec(dllimport) önce <a0></a0> Bu verilere, DLL dosyasından verilen zaman fazladan bir yönlendirme düzeyi yapmak, anımsamak zorunda kaldı yapısındaki:
// project.h#ifdef _DLL     // If accessing the data from inside the DLL   ULONG ulDataInDll;else            // If accessing the data from outside the DLL   ULONG *ulDataInDll;#endif				
, ardından verileri .def dosyanıza vermek:
// project.defLIBRARY projectEXPORTS    ulDataInDll   CONSTANT				
ve DLL dışında erişim:
if (*ulDataInDll == 0L) {   // Do stuff here}				
verileri __declspec(dllimport) olarak işaretlemek, derleyici otomatik olarak yönlendirme kod sizin için oluşturur. Artık yukarıdaki adımları hakkında endişelenmeniz gerekmez. Yukarıda belirtildiği gibi DLL oluştururken _declspec(dllimport) bildirimi veri kullanmayın. DLL işlevlerinde adres tablosu alma, veri nesnesine erişmeye kullanmayacaktır. Bu nedenle, ek yönlendirme mevcut düzeyini olmayacak.

Verileri otomatik olarak bir DLL dosyasından vermek için <a0></a0>, bu bildirimi kullanın:
__declspec(dllexport) ULONG ulDataInDLL;				

Bir .def dosyası kullanma

__Declspec(dllimport) bir .def dosyası ile birlikte kullanmayı seçerseniz, yanlış kodlama sorun oluşturacağını olasılığını azaltmak için SABIT yerine VERI kullanmak için .def dosyası değiştirmelisiniz:
// project.defLIBRARY projectEXPORTS    ulDataInDll   DATA				
aşağıdaki grafik neden gösterir:
Keyword     Emits in the import lib     ExportsCONSTANT    __imp_ulDataInDll           ulDataInDll            __ulDataInDllDATA        __imp_ulDataInDll           ulDataInDll				
_declspec (dllimport) ve SABIT kullanma __imp_ sürümü hem de açık bağlama izin vermek için oluşturulan .LIB DLL alma kitaplığındaki undecorated adını listeler. _Declspec(DllImport) ve VERI kullanarak, yalnızca ad __imp_ sürümünü listeler.

SABITINI kullanırsanız, aşağıdaki kod yapýlarýný birini ulDataInDll erişmek için kullanılabilir:
__declspec(dllimport) ULONG ulDataInDll; /*prototype*/    if (ulDataInDll == 0L)   /*sample code fragment*/ 				
-VEYA-
ULONG *ulDataInDll;      /*prototype*/ if (*ulDataInDll == 0L)  /*sample code fragment*/ 				
VERI .def dosyanızda kullanırsanız, yalnızca aşağıdaki tanımıyla derlenmiş kod değişken ulDataInDll ancak erişebilirsiniz:
__declspec(dllimport) ULONG ulDataInDll;if (ulDataInDll == 0L)   /*sample code fragment*/ 				
ek yönlendirme düzeyini kullanmak unutursanız, olası alma adresi tablonun işaretçi değişkeni--değişken kendisini erişebilecek kullanarak CONSTANT daha tehlikelidir çünkü. Bu tür bir adres tablosu alma linkers ve Microsoft derleyici tarafından salt okunur yapılan geçerli için erişim ihlali genellikle listesi.

Bu durumda bu hesap için .def dosyası içinde SABIT görür, geçerli Visual C++ linker bir uyarı verir. Yalnızca gerçek nedeni SABITINI kullanırsanız, burada üstbilgi dosyası üzerinde prototip dllimport liste belgemde bazı nesne dosyasını yeniden başlatamıyor, olur.
Referanslar
Visual C++ Books Online'da sağlayan önemli miktarda bir belge dllexport ve dllimport depolama sınıfı öznitelikleri. Bu, programlama teknikleri başvuru "DLL Win32 için oluşturma" bölümde "Dllexport ve dllimport öznitelikleri" ve C++ Dil Başvurusu, "Microsoft özgü değiştiriciler" bölüm "Using dllimport ve C++ içinde dllexport" konularında "Simgeleri verme" konuları içerir. Kapsamlı bir listesi için ilgili konular Books Online'da "dllimport" veya "dllexport" için arama yapın.

Daha fazla bilgi için, aşağıdaki Microsoft Knowledge Base makalelerine bakın:
90530Nasıl yapılır: bir DLL DOSYASı veya uygulama veri ver
107501BILGI: __declspec, Visual C++ 32-bit olarak değiştirilen __export

Uyarı: Bu makalenin çevirisi otomatik olarak yapılmıştır

Özellikler

Makale No: 132044 - Son İnceleme: 12/04/2015 11:35:07 - Düzeltme: 2.0

Microsoft Visual C++ 1.0 Professional Edition, Microsoft Visual C++ 2.0 Professional Edition, Microsoft Visual C++ 2.1, Microsoft Visual C++ 4.0 Standard Edition, Microsoft Visual C++ 5.0 Enterprise Edition, Microsoft Visual C++ 5.0 Professional Edition

  • kbnosurvey kbarchive kbmt kbcode kbcompiler kbinfo KB132044 KbMttr
Geri bildirim