Bagikan melalui


Mengimpor panggilan fungsi menggunakan __declspec(dllimport)

Menganotasi panggilan dengan menggunakan __declspec(dllimport) dapat membuatnya lebih cepat. __declspec(dllimport) selalu diperlukan untuk mengakses data DLL yang diekspor.

Mengimpor fungsi dari DLL

Contoh kode berikut menunjukkan cara menggunakan __declspec(dllimport) untuk mengimpor panggilan fungsi dari DLL ke dalam aplikasi. Asumsikan bahwa func1 adalah fungsi yang berada dalam DLL terpisah dari file yang dapat dieksekusi yang berisi fungsi utama .

Tanpa __declspec(dllimport), diberikan kode ini:

int main(void)
{
   func1();
}

compiler menghasilkan kode yang terlihat seperti ini:

call func1

dan linker menerjemahkan panggilan ke dalam sesuatu seperti ini:

call 0x4000000         ; The address of 'func1'.

Jika func1 ada di DLL lain, linker tidak dapat menyelesaikan alamat ini secara langsung karena tidak memiliki cara untuk mengetahui alamatnya func1 . Di lingkungan 32-bit dan 64-bit, linker menghasilkan thunk pada alamat yang diketahui. Di lingkungan 32-bit, thunk terlihat seperti:

0x40000000:    jmp DWORD PTR __imp_func1

Berikut __imp_func1 adalah alamat untuk func1 slot dalam tabel alamat impor file yang dapat dieksekusi. Semua alamat ini diketahui oleh linker. Loader hanya perlu memperbarui tabel alamat impor file yang dapat dieksekusi pada waktu muat agar semuanya berfungsi dengan benar.

Itu sebabnya penggunaan __declspec(dllimport) lebih baik: karena linker tidak menghasilkan thunk jika tidak diperlukan. Thunks membuat kode lebih besar (pada sistem RISC, bisa beberapa instruksi) dan dapat menurunkan performa cache Anda. Jika Anda memberi tahu pengkompilasi bahwa fungsi berada dalam DLL, fungsi tersebut dapat menghasilkan panggilan tidak langsung untuk Anda.

Jadi sekarang kode ini:

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

menghasilkan instruksi ini:

call DWORD PTR __imp_func1

Tidak ada thunk dan tidak ada jmp instruksi, sehingga kode lebih kecil dan lebih cepat. Anda juga bisa mendapatkan efek yang sama tanpa __declspec(dllimport) menggunakan pengoptimalan seluruh program. Untuk informasi selengkapnya, lihat /GL (Pengoptimalan Seluruh Program).

Untuk panggilan fungsi dalam DLL, Anda tidak ingin menggunakan panggilan tidak langsung. Linker sudah tahu alamat fungsi. Dibutuhkan waktu dan ruang ekstra untuk memuat dan menyimpan alamat fungsi sebelum panggilan tidak langsung. Panggilan langsung selalu lebih cepat dan lebih kecil. Anda hanya ingin menggunakan __declspec(dllimport) saat memanggil fungsi DLL dari luar DLL itu sendiri. Jangan gunakan __declspec(dllimport) pada fungsi di dalam DLL saat membangun DLL tersebut.

Lihat juga

Mengimpor ke dalam Aplikasi