Extern C และ C ABI
เปิดเผยส่วนเชื่อมต่อที่เข้ากันได้กับ C จากไลบรารี C++ ด้วย extern C
Extern C และ C ABI เป็นบทเรียน C++ Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C++ Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน
เหตุใดจึงต้องเชื่อมการทำงานระหว่างภาษา
C++ มี ABI ที่ซับซ้อน (ส่วนติดต่อไบนารีของแอปพลิเคชัน) ซึ่งรวมถึงการปรับแต่งชื่อ ข้อยกเว้น และแม่แบบ ภาษาอื่น (C, Python, Rust) ไม่สามารถใช้สัญลักษณ์ C++ ที่ผ่านการปรับแต่งชื่อโดยตรงได้
extern "C"
ครอบการประกาศด้วย extern "C" เพื่อปิดการปรับแต่งชื่อของ C++ และใช้รูปแบบการเรียกฟังก์ชันของ C
extern "C" {
void greet(const char* name);
int add(int a, int b);
}เหตุใดจึงใช้ C ABI
ABI ของ C เป็นส่วนร่วมพื้นฐานที่สุดระหว่างภาษาแทบทุกภาษา ภาษาเกือบทั้งหมดสามารถเรียกฟังก์ชัน C ผ่าน FFI ได้
รูปแบบไฟล์ส่วนหัว
ทำให้ไฟล์ส่วนหัวใช้งานได้ทั้งจาก C และ C++ ด้วย extern "C" แบบมีเงื่อนไข
#ifdef __cplusplus
extern "C" {
#endif
void hello(void);
int sum(int a, int b);
#ifdef __cplusplus
}
#endifสิ่งที่ส่งออกไม่ได้
คุณลักษณะบางอย่างของ C++ ไม่มีสิ่งเทียบเท่าใน C:
- คลาส (C ไม่มีแนวคิดเรื่องคลาส)
- แม่แบบ (แก้ไขระหว่างการคอมไพล์ จึงส่งออกไม่ได้)
- ฟังก์ชันที่มีหลายรูปแบบ (เมื่อไม่มีการปรับแต่งชื่อ จึงไม่มีการโอเวอร์โหลด)
- ข้อยกเว้น (ต้องจับก่อนข้าม FFI)
การเปิดให้ใช้งานคลาส
ซ่อนคลาสไว้เบื้องหลังตัวชี้แบบทึบและส่วนติดต่อรูปแบบ C
// header (C visible)
typedef struct Widget Widget;
Widget* widget_create(int x);
void widget_destroy(Widget*);
int widget_value(const Widget*);
// .cpp
class WidgetImpl { /* ... */ };
extern "C" {
Widget* widget_create(int x) { return reinterpret_cast<Widget*>(new WidgetImpl(x)); }
void widget_destroy(Widget* w) { delete reinterpret_cast<WidgetImpl*>(w); }
}หลีกเลี่ยงข้อยกเว้นข้าม FFI
ข้อยกเว้นที่ถูกโยนจากฟังก์ชัน C++ ซึ่งถูกเรียกผ่าน C จะทำให้โปรแกรมยุติการทำงาน ให้จับข้อยกเว้นที่ขอบเขตการเชื่อมต่อ
extern "C" int safe_call() {
try {
risky();
return 0;
} catch (...) {
return -1;
}
}ความเป็นเจ้าของหน่วยความจำ
ระบุให้ชัดเจนว่าใครเป็นเจ้าของสิ่งใด — โดยทั่วไป ฝั่งที่จัดสรรหน่วยความจำจะเป็นผู้คืนหน่วยความจำ ความไม่สอดคล้องกันทำให้เกิดหน่วยความจำรั่วหรือการคืนหน่วยความจำซ้ำ
สตริงข้าม FFI
std::string ใช้ได้เฉพาะใน C++ เท่านั้น ให้ส่งข้าม FFI เป็น const char* ตัดสินใจว่าฝั่งรับจะคัดลอกข้อมูลหรือไม่ และระบุอายุการใช้งานให้ชัดเจน
โครงสร้างข้าม FFI
ใช้โครงสร้าง POD (ข้อมูลแบบดั้งเดิม) ที่มีผังหน่วยความจำเหมือนกันใน C และ C++ หลีกเลี่ยงฟังก์ชันเสมือน การอ้างอิง หรือชนิดข้อมูลของไลบรารีมาตรฐาน
ฟังก์ชันเรียกกลับ
ส่งตัวชี้ฟังก์ชัน (หรือตัวชี้ void* + ตัวชี้ฟังก์ชัน) ข้าม FFI จัดเตรียมตัวชี้บริบทสำหรับฟังก์ชันปิดล้อม
extern "C" {
typedef void (*Callback)(int value, void* user_data);
void register_callback(Callback cb, void* user_data);
}การเชื่อมโยงและไฟล์ส่วนหัว
extern "C" มีผลเฉพาะต่อการเชื่อมโยง ไม่ใช่พฤติกรรม ฟังก์ชันยังคงคอมไพล์ภายในแบบ C++ แต่สามารถเรียกจากภายนอกในฐานะ C ได้
ตรวจสอบความเข้าใจ
เหตุใดจึงครอบฟังก์ชัน C++ ด้วย extern "C" เมื่อต้องการเปิดให้ภาษาอื่นใช้งาน
สรุปทบทวน
extern "C" ทำให้ฟังก์ชันมีการเชื่อมโยงแบบ C — ไม่มีการปรับแต่งชื่อและใช้รูปแบบการเรียกฟังก์ชันของ C ใช้สิ่งนี้เพื่อเปิดให้ภาษาอื่นเรียกใช้ C++ ผ่าน FFI ซ่อนคลาสไว้เบื้องหลังตัวชี้แบบทึบ จับข้อยกเว้นที่ขอบเขตการเชื่อมต่อ และระบุความเป็นเจ้าของให้ชัดเจน
คำถามที่พบบ่อย
บทเรียน “Extern C และ C ABI” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “Extern C และ C ABI” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C++ Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “Extern C และ C ABI”
เปิดเผยส่วนเชื่อมต่อที่เข้ากันได้กับ C จากไลบรารี C++ ด้วย extern C คุณปฏิบัติ C++ Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C++ Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C++ Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน
บทเรียน “Extern C และ C ABI” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C++ Academy นี้ได้ไหม
ได้ บทเรียน C++ Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- Extern C และ C ABI
- การเรียกใช้ Python จาก C++ ผ่าน pybind11
- C++ สำหรับขอบเขตการเชื่อมต่อ Rust FFI
- การใช้ SWIG สำหรับการเชื่อมโยงหลายภาษา