0Pricing
C++ Academy · บทเรียน

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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. Extern C และ C ABI
  2. การเรียกใช้ Python จาก C++ ผ่าน pybind11
  3. C++ สำหรับขอบเขตการเชื่อมต่อ Rust FFI
  4. การใช้ SWIG สำหรับการเชื่อมโยงหลายภาษา
← กลับไปที่ C++ Academy