ฉันเห็นซอร์สโค้ด Qt ดังนี้:
class Q_CORE_EXPORT QBasicAtomicInt
{
public:
...
};
Q_CORE_EXPORT
มาโครใดที่กำหนดไว้ด้านล่าง:
define Q_DECL_IMPORT __declspec(dllimport)
แล้วมัน__declspec(dllimport)
หมายความว่าอย่างไร?
ฉันเห็นซอร์สโค้ด Qt ดังนี้:
class Q_CORE_EXPORT QBasicAtomicInt
{
public:
...
};
Q_CORE_EXPORT
มาโครใดที่กำหนดไว้ด้านล่าง:
define Q_DECL_IMPORT __declspec(dllimport)
แล้วมัน__declspec(dllimport)
หมายความว่าอย่างไร?
คำตอบ:
__declspec
เป็นแอตทริบิวต์เฉพาะของ Microsoft ที่อนุญาตให้คุณระบุข้อมูลระดับพื้นที่เก็บข้อมูล
(มุมของ Nitpicker: อย่างไรก็ตามผู้จำหน่ายคอมไพเลอร์อื่น ๆ อีกจำนวนหนึ่งเช่น GCC สนับสนุนส่วนขยายภาษานี้เพื่อความเข้ากันได้กับฐานรหัสที่ติดตั้งซึ่งเขียนขึ้นโดยกำหนดเป้าหมายเป็นคอมไพเลอร์ของ Microsoft บางรายยังมีแอตทริบิวต์ระดับพื้นที่จัดเก็บเพิ่มเติม)
สองของผู้ที่แอตทริบิวต์การจัดเก็บข้อมูลระดับที่สามารถระบุและdllimport
dllexport
สิ่งเหล่านี้ระบุให้คอมไพเลอร์ทราบว่าฟังก์ชันหรืออ็อบเจ็กต์ถูกอิมพอร์ตหรือเอ็กซ์พอร์ต (ตามลำดับ) จาก DLL
โดยเฉพาะอย่างยิ่งพวกเขากำหนดอินเทอร์เฟซของ DLL ให้กับไคลเอนต์โดยไม่ต้องใช้ไฟล์ module-definition ( .DEF
) คนส่วนใหญ่พบว่าการใช้นามสกุลภาษาเหล่านี้ง่ายกว่าการสร้างไฟล์ DEF
ด้วยเหตุผลที่ชัดเจน__declspec(dllimport)
และ__declspec(dllexport)
โดยทั่วไปมักจับคู่กัน คุณใช้dllexport
เพื่อทำเครื่องหมายสัญลักษณ์ว่าส่งออกจาก DLL และคุณใช้dllimport
เพื่ออิมพอร์ตสัญลักษณ์ที่เอ็กซ์พอร์ตนั้นในไฟล์อื่น
ด้วยเหตุนี้และเนื่องจากโดยทั่วไปไฟล์ส่วนหัวเดียวกันจึงถูกใช้ทั้งในการคอมไพล์ DLL และในโค้ดไคลเอนต์ที่ใช้อินเทอร์เฟซของ DLL จึงเป็นรูปแบบทั่วไปในการกำหนดมาโครที่จะแก้ไขโดยอัตโนมัติเป็นตัวระบุแอตทริบิวต์ที่เหมาะสมในเวลาคอมไพล์ ตัวอย่างเช่น:
#if COMPILING_DLL
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT __declspec(dllimport)
#endif
DLLEXPORT
และจากนั้นทำเครื่องหมายสัญลักษณ์ทั้งหมดที่ควรจะส่งออกด้วย
สันนิษฐานว่าคือสิ่งที่Q_CORE_EXPORT
แมโครไม่แก้ไขปัญหาอย่างใดอย่างหนึ่งหรือQ_DECL_IMPORT
Q_DECL_EXPORT
__declspec
สัญกรณ์เพื่อเป็นส่วนขยายของภาษา C ++ ฉันเชื่อว่า GCC รองรับแล้ว แต่ส่วนใหญ่เป็นเพราะเหตุผลด้านความเข้ากันได้กับคอมไพเลอร์ของ Microsoft และฉันไม่เข้าใจว่า "เฉพาะ MS" แตกต่างจาก "คอมไพเลอร์เฉพาะ" อย่างไร Microsoft เขียนคอมไพเลอร์ C ++ และมีผู้คนจำนวนมากใช้งาน มาพร้อมกับ Visual Studio
__declspec(dllimport)
เป็นตัวระบุคลาสหน่วยเก็บข้อมูลที่บอกคอมไพลเลอร์ว่าฟังก์ชันหรืออ็อบเจ็กต์หรือชนิดข้อมูลถูกกำหนดไว้ใน DLL ภายนอก
ฟังก์ชันหรือวัตถุหรือชนิดข้อมูลจะถูกส่งออกจาก DLL ที่มีไฟล์__declspec(dllexport)
.
__declspec(dllexport)
บอกให้คอมไพเลอร์แจ้งผู้เชื่อมโยงว่าต้องวางสัญลักษณ์เหล่านี้ในตารางการส่งออก (เมื่อรวบรวม. dll) เมื่อคอมไพล์โปรแกรมที่เชื่อมโยงกับ. dll __declspec(dllimport)
บอกคอมไพลเลอร์ให้สร้างการเรียกทางอ้อมที่สัมพันธ์กับการลงทะเบียนแบบสัมบูรณ์(ซึ่งตัวเชื่อมโยงจะกรอกคำแก้ไขเพื่อชี้ไปที่ตารางนำเข้า) แทนที่จะเป็นทะเบียนญาติ rip-relative -directตามปกติคำสั่งการโทรทางอ้อมไปยังฟังก์ชันที่ไม่ได้กำหนด (ซึ่งไม่สามารถแก้ไขคำสั่งได้ตัวเชื่อมโยงจะแทรกที่อยู่สัมพัทธ์ของ thunk จากนั้นสร้าง thunk ซึ่งภายในจะวางการเรียกทางอ้อมที่สัมพันธ์กันโดยสมบูรณ์แบบสัมพันธ์กับ ตัวชี้ฟังก์ชันในตารางการนำเข้า) นี่คือขนาดรหัสและการเพิ่มประสิทธิภาพความเร็ว เป็นไลบรารีอิมพอร์ต. lib ที่บอกผู้เชื่อมโยงว่าจะนำเข้าสัญลักษณ์ใดและใช้เป็นแนวทางในการสร้างตารางการนำเข้าและสร้างสิ่งที่จำเป็นในเซ็กเมนต์. 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 / import-data-using-Declspec-dllimport? view = vs-2019 https://stackoverflow.com/a/4490536/7194773
หมายความว่านิยามของฟังก์ชันอยู่ในไดนามิกไลบรารี โปรดดูเอกสารสำหรับรายละเอียดและตัวอย่างเพิ่มเติม