Genel Kurallar ve Sınırlamalar
Microsoft'a Özgü
veya özniteliği olmayan
dllimport
dllexport
bir işlev veya nesne bildirirseniz, işlev veya nesne DLL arabiriminin parçası olarak kabul edilmez. Bu nedenle, işlevin veya nesnenin tanımı bu modülde veya aynı programın başka bir modülünde bulunmalıdır. İşlevi veya nesneyi DLL arabiriminin bir parçası yapmak için, diğer modüldeki işlevin veya nesnenin tanımını olarakdllexport
bildirmeniz gerekir. Aksi takdirde bağlayıcı hatası oluşturulur.özniteliğine sahip
dllexport
bir işlev veya nesne bildirirseniz, tanımı aynı programın bazı modüllerinde görünmelidir. Aksi takdirde bağlayıcı hatası oluşturulur.Programınızdaki tek bir modül aynı işlev veya nesne için hem hem de
dllimport
dllexport
bildirimleri içeriyorsa,dllexport
öznitelik özniteliğindendllimport
önceliklidir. Ancak, bir derleyici uyarısı oluşturulur. Örnek:__declspec( dllimport ) int i; __declspec( dllexport ) int i; // Warning; inconsistent; // dllexport takes precedence.
C++'ta, genel olarak bildirilen veya statik yerel veri işaretçisini veya özniteliğiyle bildirilen bir veri nesnesinin adresiyle
dllimport
başlatabilirsiniz ve bu da C'de bir hata oluşturur. Ayrıca, özniteliğiyle bildirilen bir işlevin adresiyle statik bir yerel işlev işaretçisidllimport
başlatabilirsiniz. C'de, böyle bir atama işaretçiyi işlevin adresi yerine DLL içeri aktarma thunk'unun (denetimi işleve aktaran bir kod saplaması) adresine ayarlar. C++ dilinde işaretçiyi işlevin adresine ayarlar. Örnek:__declspec( dllimport ) void func1( void ); __declspec( dllimport ) int i; int *pi = &i; // Error in C static void ( *pf )( void ) = &func1; // Address of thunk in C, // function in C++ void func2() { static int *pi = &i; // Error in C static void ( *pf )( void ) = &func1; // Address of thunk in C, // function in C++ }
Ancak, bir nesnenin bildiriminde özniteliğini
dllexport
içeren bir programın bu nesnenin tanımını programda herhangi bir yerde sağlaması gerektiğinden, işlevin adresiyle genel veya yerel birdllexport
statik işlev işaretçisi başlatabilirsiniz. Benzer şekilde, veri nesnesinin adresiyle genel veya yerel birdllexport
statik veri işaretçisi başlatabilirsiniz. Örneğin, aşağıdaki kod C veya C++'da hata oluşturmaz:__declspec( dllexport ) void func1( void ); __declspec( dllexport ) int i; int *pi = &i; // Okay static void ( *pf )( void ) = &func1; // Okay void func2() { static int *pi = &i; // Okay static void ( *pf )( void ) = &func1; // Okay }
olarak
dllexport
işaretlenmemiş bir temel sınıfı olan normal bir sınıfa uygularsanızdllexport
, derleyici C4275 oluşturur.Derleyici, temel sınıf bir sınıf şablonunun uzmanlığıysa aynı uyarıyı oluşturur. Bu sorunu geçici olarak çözmek için temel sınıfı ile
dllexport
işaretleyin. Sınıf şablonunun özelleştirilmesiyle ilgili sorun, öğesinin yerleştirileceği__declspec(dllexport)
yerdir; sınıf şablonunu işaretlemenize izin verilmez. Bunun yerine, sınıf şablonunu açıkça örneği oluşturup bu açık örneklemeyi iledllexport
işaretleyin. Örnek:template class __declspec(dllexport) B<int>; class __declspec(dllexport) D : public B<int> { // ...
Şablon bağımsız değişkeni türetilen sınıfsa bu geçici çözüm başarısız olur. Örnek:
class __declspec(dllexport) D : public B<D> { // ...
Bu şablonlarda yaygın bir desen olduğundan, derleyici bir veya daha fazla temel sınıfı olan bir sınıfa uygulandığında ve temel sınıflardan biri veya daha fazlası bir sınıf şablonunun uzmanlığı olduğunda semantiğini
dllexport
değiştirdi. Bu durumda, derleyici örtük olarak sınıf şablonlarının uzmanlıkları için geçerlidirdllexport
. Aşağıdakileri yapabilir ve uyarı alamayabilirsiniz:class __declspec(dllexport) D : public B<D> { // ...
END Microsoft'a Özgü
Ayrıca bkz.
Geri Bildirim
https://aka.ms/ContentUserFeedback.
Çok yakında: 2024 boyunca, içerik için geri bildirim mekanizması olarak GitHub Sorunları’nı kullanımdan kaldıracak ve yeni bir geri bildirim sistemiyle değiştireceğiz. Daha fazla bilgi için bkz.Gönderin ve geri bildirimi görüntüleyin