apa sebenarnya arti __declspec (dllimport)?

92

Saya melihat kode sumber Qt seperti ini:

class Q_CORE_EXPORT QBasicAtomicInt
{
public:
...
};

Q_CORE_EXPORTMakro mana yang mendefinisikan seperti di bawah ini:

define Q_DECL_IMPORT __declspec(dllimport)

Jadi apa __declspec(dllimport)sebenarnya artinya?

gemfield
sumber

Jawaban:

118

__declspecadalah atribut khusus Microsoft yang memungkinkan Anda menentukan informasi kelas penyimpanan.
(Sudut Nitpicker: Namun, sejumlah vendor kompilator lain — misalnya GCC — sekarang mendukung ekstensi bahasa ini untuk kompatibilitas dengan basis kode terinstal yang ditulis menargetkan kompiler Microsoft. Beberapa bahkan menyediakan atribut kelas penyimpanan tambahan.)

Dua dari atribut kelas penyimpanan yang dapat ditentukan adalah dllimportdan dllexport. Ini menunjukkan kepada kompiler bahwa suatu fungsi atau objek diimpor atau diekspor (masing-masing) dari DLL.

Lebih khusus lagi, mereka mendefinisikan antarmuka DLL ke klien tanpa memerlukan file module-definition ( .DEF). Kebanyakan orang merasa lebih mudah menggunakan ekstensi bahasa ini daripada membuat file DEF.

Untuk alasan yang jelas, __declspec(dllimport)dan __declspec(dllexport)umumnya dipasangkan satu sama lain. Anda gunakan dllexportuntuk menandai simbol yang diekspor dari DLL, dan Anda gunakan dllimportuntuk mengimpor simbol yang diekspor itu ke file lain.

Karena itu, dan karena file header yang sama umumnya digunakan baik saat menyusun DLL dan dalam kode klien yang menggunakan antarmuka DLL, itu adalah pola umum untuk menentukan makro yang secara otomatis menyelesaikan penentu atribut yang sesuai pada waktu kompilasi. Sebagai contoh:

#if COMPILING_DLL
    #define DLLEXPORT __declspec(dllexport)
#else
    #define DLLEXPORT __declspec(dllimport)
#endif

Dan kemudian menandai semua simbol yang harus diekspor dengan DLLEXPORT.

Agaknya, itulah yang dilakukan Q_CORE_EXPORTmakro, menyelesaikan ke salah satu Q_DECL_IMPORTatau Q_DECL_EXPORT.

Cody Grey
sumber
__declspec tidak benar "khusus-MS" (ini jauh lebih "spesifik kompiler) dan beberapa kompiler menggunakan deklarasi ini juga untuk beberapa platform. Beberapa nilai atributnya adalah (dllexport / dllimports adalah khusus MS, pada kenyataannya, karena DLL adalah MS lexicon).
Emilio Garavaglia
9
@Emilio: Sejauh yang saya ketahui, Microsoft menemukan __declspecnotasi sebagai ekstensi untuk bahasa C ++. Saya percaya bahwa GCC sekarang mendukungnya, tetapi itu terutama karena alasan kompatibilitas dengan kompiler Microsoft. Dan saya tidak mengerti bagaimana "spesifik-MS" berbeda dari "spesifik kompiler". Microsoft menulis kompiler C ++ dan banyak orang menggunakannya. Itu datang dengan Visual Studio.
Cody Gray
8
Microsoft membuat kompiler. Ini disebut "Microsoft C / C ++ Optimizing Compiler", cl.exe. Banyak orang secara keliru menyebut Visual Studio seolah-olah itu adalah kompiler, tetapi itu adalah IDE. Saya tidak tahu mengapa orang memilih-milih tentang apa arti "khusus Microsoft". Ini tidak berarti "lingkungan MS" (apapun itu), dan tentu saja tidak berarti "Windows". Ya, vendor kompilator lain sekarang mendukung ekstensi untuk kompatibilitas dengan basis terinstal kode tertulis yang menargetkan kompiler Microsoft. Seperti yang saya katakan sebelumnya, sejauh yang saya ketahui, Microsoft yang menemukan sintaks. Itulah poin yang dibuat di sini.
Cody Grey
2
@CodyGray: Microsoft telah menemukannya sendiri tidak akan cukup. Namun Microsoft telah menemukannya, tidak ada standar yang mengandungnya, yang lain hanya menerapkannya untuk kompatibilitas dan digunakan terutama (jika tidak secara eksklusif) untuk program yang menargetkan Microsoft Windows bersama-sama membuat poin yang sangat kuat untuk menyebutnya "khusus Microsoft"
celtschk
6
Ini adalah jawaban yang luar biasa, terutama bagian tentang "karena file header yang sama biasanya digunakan baik saat menyusun DLL dan dalam kode klien"! Menjadikan setiap aspek impor / ekspor-barang sangat jelas.
Ela782
30

__declspec(dllimport) adalah penentu kelas penyimpanan yang memberi tahu kompiler bahwa fungsi atau objek atau tipe data didefinisikan dalam DLL eksternal.

Fungsi atau objek atau tipe data diekspor dari DLL dengan yang sesuai __declspec(dllexport).

arx
sumber
6
Baik. Akhirnya, setelah 2 jam membaca, saya menemukan pernyataan yang paling memuaskan, paling ringkas, dan akurat tentang apa yang saya inginkan.
el psy Congroo
1

__declspec(dllexport)memberi tahu kompiler untuk memberi tahu linker bahwa simbol-simbol ini perlu ditempatkan di tabel ekspor (saat menyusun .dll). Saat mengompilasi program yang terhubung dengan .dll, __declspec(dllimport)memberi tahu compiler untuk menghasilkan panggilan rip-relative absolute register-indirect indirect (yang akan diisi oleh linker untuk menunjuk ke tabel impor) daripada rip-relative register-direct biasa.instruksi panggilan tidak langsung ke fungsi yang tidak ditentukan (yang, karena tidak dapat memodifikasi instruksi, linker memasukkan alamat relatif dari sebuah thunk dan kemudian membuat thunk, di dalamnya ia menempatkan pemanggilan rip-relative absolute register-indirect indirect ke penunjuk fungsi dalam tabel impor). Ini adalah ukuran kode dan pengoptimalan kecepatan. Ini adalah pustaka impor .lib yang memberi tahu linker simbol mana yang akan diimpor dan digunakan sebagai panduan untuk membuat tabel impor dan membuat hal-hal yang diperlukan di segmen .text.

https://docs.microsoft.com/en-us/cpp/build/importing-function-calls-using-declspec-dllimport?view=vs-2019 https://docs.microsoft.com/en-us/cpp / build / importing-data-using-decspec-dllimport? view = vs-2019 https://stackoverflow.com/a/4490536/7194773

Lewis Kelsey
sumber
-2

Artinya definisi fungsi tersebut ada di library dinamis. Lihat dokumentasi untuk detail dan contoh lebih lanjut.

Armen Tsirunyan
sumber