__declspec คืออะไรและฉันต้องใช้เมื่อใด


157

ฉันได้เห็นอินสแตนซ์ของ__declspecรหัสที่ฉันกำลังอ่านอยู่ มันคืออะไร? และเมื่อใดที่ฉันจะต้องใช้โครงสร้างนี้


1
หากคุณโชคร้ายและย้ายจาก Linux ไปยัง Windows คุณอาจเสียเวลาลองคิดดูว่าเหตุใด DLLs ของคุณจึงไม่ทำงานจนกว่าคุณจะพบว่าคุณต้องเพิ่ม__declspec(dllexport)ก่อนหน้าที่แต่ละหน้าที่ในไลบรารีของคุณ
SomethingSomething

คำตอบ:


74

นี่เป็นส่วนขยายเฉพาะของ Microsoft สำหรับภาษา C ++ ซึ่งช่วยให้คุณสามารถระบุประเภทหรือฟังก์ชั่นที่มีข้อมูลคลาสหน่วยเก็บข้อมูล

เอกสาร

__declspec (C ++)


19
ขอบคุณ - แต่ฉันจะใช้เพื่ออะไร
สกอตต์ J

4
สำหรับการประกาศอินเตอร์เฟสและคลาส COM ตัวอย่างเช่นคุณใช้ __declspec (uuid) สำหรับการส่งออกฟังก์ชั่นส่งไฟล์ DEF ที่คุณใช้ __declspec (dllexport) เป็นต้นรายการทั้งหมดค่อนข้างยาว
Seva Alekseyev

1
@ScottJ ฉันใช้มันสำหรับคุณสมบัติอย่างต่อเนื่อง: __declspec (คุณสมบัติ (get = X put = X)) ตัวระบุชนิดข้อมูล MSDN มีรายละเอียดเพิ่มเติมแน่นอน ในฐานะที่เป็น "โปรแกรมเมอร์ C # ถึง C / C ++" มันเป็นความสุข!
MasterMastic

51

ตัวอย่างที่ยอมรับได้คือ__declspec(dllimport)และ__declspec(dllexport)ซึ่งแนะนำให้ linker เพื่อนำเข้าและส่งออก (ตามลำดับ) สัญลักษณ์จากหรือไปยัง DLL

// header
__declspec(dllimport) void foo();


// code - this calls foo() somewhere in a DLL
foo();

( __declspec(..)เพียงห่อสิ่งที่เฉพาะเจาะจงของ Microsoft - เพื่อให้ได้ความเข้ากันได้โดยปกติแล้วหนึ่งจะห่อด้วยแมโคร)


8
@ Tetris คุณไม่ทราบจากรหัส การตัดสินใจทำโดย linker ที่จะเลือกคนแรกที่.libพบว่ามีสัญลักษณ์ส่งออกที่ตรงกัน
Euro Micelli

19

ส่วนใหญ่จะใช้สำหรับการนำเข้าสัญลักษณ์จาก / ส่งออกสัญลักษณ์ไปยัง shared library (DLL) ทั้ง Visual C ++ และ GCC สนับสนุนคอมไพเลอร์และ__declspec(dllimport) __declspec(dllexport)ใช้อื่น ๆ (บางคนไมโครซอฟท์เท่านั้น) ได้รับการบันทึกใน MSDN


12

อีกตัวอย่างหนึ่งเพื่อแสดงคำหลัก__declspec :

เมื่อคุณกำลังเขียนโปรแกรมควบคุมเคอร์เนลของ Windows บางครั้งคุณต้องการเขียนลำดับโค้ด prolog / epilog ของคุณเองโดยใช้รหัสแอสเซมเบลอร์อินไลน์ดังนั้นคุณจึงสามารถประกาศฟังก์ชันของคุณด้วยแอตทริบิวต์เปลือยกาย

__declspec( naked ) int func( formal_parameters ) {}

หรือ

#define Naked __declspec( naked )
Naked int func( formal_parameters ) {}

โปรดอ้างอิงถึงnaked (C ++)


8

โดยพื้นฐานแล้วเป็นวิธีที่ Microsoft แนะนำส่วนขยาย C ++ เพื่อไม่ให้ขัดแย้งกับส่วนขยายในอนาคตของ C ++ มาตรฐาน ด้วย __declspec คุณสามารถกำหนดฟังก์ชั่นหรือคลาสได้ ความหมายที่แท้จริงนั้นแตกต่างกันไปตามลักษณะของ __declspec ตัวอย่างเช่น __declspec (เปลือยกาย) ยับยั้งการสร้าง prolog / epilog (สำหรับตัวจัดการอินเตอร์รัปต์โค้ดที่ฝังได้ ฯลฯ ), __declspec (เธรด) ทำให้ตัวแปรเธรดแบบโลคัลและอื่น ๆ

รายการทั้งหมดของแอตทริบิวต์ __declspec มีอยู่ใน MSDN และแตกต่างกันไปตามรุ่นและแพลตฟอร์มคอมไพเลอร์


1
พิจารณาคอมไพเลอร์ที่ไม่ใช่ของ Microsoft เช่นGCC 4.2ว่าทางเลือกที่เสนอนอกเหนือไปจากพวกเขา__attribute__ ((dllexport))ไป__declspec(dllexport)มันไม่ยุติธรรมที่จะโทร__declspec, ส่วนขยายของไมโครซอฟท์เท่านั้น?
user2338150

0

ฉันรู้ว่ามันได้รับแปดปี แต่ผมอยากจะแบ่งปันชิ้นส่วนของรหัสนี้พบใน MRuby ที่แสดงให้เห็นว่าสามารถใช้ผึ้งในระดับเดียวกับ__declspec()export keyword

/** Declare a public MRuby API function. */
#if defined(MRB_BUILD_AS_DLL)
#if defined(MRB_CORE) || defined(MRB_LIB)
# define MRB_API __declspec(dllexport)
#else
# define MRB_API __declspec(dllimport)
#endif
#else
# define MRB_API extern
#endif
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.