2010-08-30 18 views
5

Ben ++ VC yeniyim. Sadece bir yazılım oluşturdum ve bir .dll ve bir .lib oluşturdu. Kodumdaki işlevlerden bunu kullanmam gerek. Kodumu oluşturmak için hem .lib hem de .dll bağlantılarına ihtiyacım var mı? Bu bağlantıyı yapmak için hangi proje özelliklerini değiştirmem gerekiyor?.h, .dll ve .lib karışıklık

+0

ayrıca bkz. Http://stackoverflow.com/questions/1778111/whats-the-differences-between-dll-lib-h-files – dyp

cevap

10

Aslında, yalnızca .dll dosyasına ihtiyacınız var. İşlevlerini çalıştırmak için gerekli tüm kod ve verileri içerir. Ayrıca işlevlerin sembolik isimlerini (ör. PrintMe işlevi), ordinallerini (DLL'deki bu işlevin sayısı) ve adreslerini DLL'de bağlayan bir tablo da içerir.
Yalnızca DLL'yi kullanmak istiyorsanız, çözümlenen sembolleri "el ile" almanız gerekir:
Diyelim ki, DLL'nin PrintMe işlevini kullanmak istediğinizi varsayalım. Yapmanız gereken, adının (PrintMe) veya orjinalinin (PrintMe DLL'nin 1. işlevi) çözümlenmesidir. Bunun için, Win32 API'dan (aka Windows SDK) LoadLibrary, GetModuleHandle ve GetProcAdress'i kullanabilirsiniz. Ayrıca, bu yöntem, çalışma zamanında DLL'yi yüklemenize izin verir (aşağıya bakın).

kolay yolu, MSVC (++) özellikleri __declspec (dllexport) ve __declspec (dllimport), örn.


// your DLL 
__declspec(dllexport) void PrintMe() 
{ 
    printf("Hello World!"); 
} 

// you project to use the DLL 
__declspec(dllimport) void PrintMe(); 

Birincisi (dllexport), derleyiciye işlevi dışa aktarmasını söyler. İkincisi (dllimport) ilginç olanıdır: Bu işlevi DLL'den kullanabilmek için gereken tüm kodu oluşturur. Bunun için
, siz (DLL kullanmak isteyen) projenizde .lib dosyası gerekiyor. .lib dosyası, sembol adını (PrintMe) DLL'deki adresine çözümlemek için linker için bilgi içerir. .lib statik olarak bağlı olduğundan, bağlayıcı bunu yararlanabilir - tam tersine DLL çalışma zamanı/yükleme süresi bağlı, böylece bağlayıcı kullanamazsınız. (Evet, .lib dosyasındaki bilgiler gereksizdir.). Not: Bu yöntemi kullanarak yeni DLL dosyasını değiştiremezsiniz. Bazı yapı değişiklikleri DLL'deki işlevlerin adreslerini etkiler, bkz. this SO answer. Win32 API (LoadLibrary'ı ...) ve __declspec ile msvc yöntemiyle arasında
son bir fark DLL yüklenmesidir. LoadLibrary kullandığınızda, DLL, çalışma zamanında yüklenir, tabii ki (böylece bulunamadığında ve benzeri durumlarda özel durumları yakalayabilirsiniz). Diğer yöntem yükleme zamanında DLL'yi yükler, böylece Windows DLL bulamadığında program sonlandırır (çalışmayacak).

VS'de bir proje oluşturduğunuzda, bir sihirbazın (Win32 projesi) sonundaki "export sembolleri" onay kutusunu etkinleştirebilirsiniz. Bu size dışa aktarılan sembollerden bazı örnekler verir. Ayrıca, makro artı önişlemci defition artı çok yararlı olan bazı direktifler tanıtır:


// DLL header 

#ifdef _YOUR_DLL_EXPORTS 
#define YOUR_DLL_API __declspec(dllexport) 
#else 
#define YOUR_DLL_API __declspec(dllimport) 
#endif 

YOUR_DLL_API PrintMe(); 

Artık size DLL projesi olarak DLL oluşturmak için bu başlık dosyasını kullanabilirsiniz sahip olduğunu _YOUR_DLL_EXPORTS tanımlı (proje özellikleri sayfasına bakın C++, önişlemci). DLL kullanan proje de bu üstbilgiyi kullanabilir, ancak sonra tanımlanmış bir adı olmamalıdır. DLL dosyasını kullanmak istediğiniz projeye üstbilgi dosyası eklediğinizde, makro, __declspec (dllimport) olarak çözülür. Bu, linker'e (.lib dosyasında bulunan) bu işlevi aramasını ve DLL'yi çalışma zamanında yüklemek ve sembol adını çözmek için gerekli tüm kodu oluşturmasını söyler.

+0

+1. Bunu daha fazla oy verebilseydim. –

+1

"Import Library" olarak adlandırılan bir şeyin de bulunduğuna dikkat edilmelidir. Http://stackoverflow.com/questions/3573475/how-does-the-import-library-work-details –

+0

@WakanTanka Evet, tür .lib cevabımda bahsediyordum. Bağlantı için teşekkürler. – dyp