มีปัญหาเรื่องความสะดวกในการพกพากับ C ++ ซึ่งเป็นเพราะขาดมาตรฐานในระดับไบนารีเท่านั้น
ฉันไม่คิดว่ามันง่ายขนาดนี้ คำตอบที่ให้ไว้มีเหตุผลที่ยอดเยี่ยมเกี่ยวกับการขาดการมุ่งเน้นไปที่มาตรฐาน แต่ C ++ อาจมีภาษาที่หลากหลายเกินกว่าที่จะเหมาะสมกับการแข่งขันกับ C ในฐานะมาตรฐาน ABI อย่างแท้จริง
เราสามารถเข้าไปในชื่อ mangling ที่เกิดจากการทำงานมากเกินไป, ความไม่ลงรอยกัน vtable, ความเข้ากันไม่ได้กับข้อยกเว้นที่ข้ามขอบเขตของโมดูล, ฯลฯ ทั้งหมดนี้เป็นความเจ็บปวดที่แท้จริง, และฉันหวังว่าพวกเขาสามารถสร้างมาตรฐาน vtable
แต่มาตรฐาน ABI ไม่ได้เป็นเพียงการสร้าง C ++ dylibs ที่ผลิตในคอมไพเลอร์ตัวเดียวที่สามารถใช้งานโดยไบนารีอื่นที่สร้างโดยคอมไพเลอร์คนอื่น ABI จะใช้ข้ามภาษา มันคงจะดีถ้าอย่างน้อยพวกเขาสามารถครอบคลุมส่วนแรกได้ แต่ไม่มีทางที่ฉันจะเห็น C ++ แข่งขันกับ C ในระดับสากล ABI ได้อย่างแท้จริงดังนั้นสิ่งสำคัญสำหรับการสร้าง dylib ที่เข้ากันได้อย่างกว้างขวางที่สุด
ลองนึกภาพฟังก์ชั่นง่ายๆที่ส่งออกเช่นนี้
void f(Foo foo);
void f(Bar bar, int val);
... และจินตนาการFoo
และBar
เป็นคลาสที่มีตัวสร้างพารามิเตอร์, ตัวสร้างแบบคัดลอก, ตัวสร้างการย้ายและตัวทำลายแบบไร้สาระ
จากนั้นใช้สถานการณ์ของ Python / Lua / C # / Java / Haskell / etc นักพัฒนาพยายามนำเข้าโมดูลนี้และใช้ในภาษาของพวกเขา
ก่อนอื่นเราต้องใช้ชื่อ mangling สำหรับวิธีการส่งออกสัญลักษณ์โดยใช้ฟังก์ชั่นการโอเวอร์โหลด นี่เป็นส่วนที่ง่ายกว่า แต่มันไม่ควรเป็นชื่อ "mangling" เนื่องจากผู้ใช้ dylib ต้องค้นหาสัญลักษณ์ตามชื่อโอเวอร์โหลดที่นี่ควรนำไปสู่ชื่อที่ดูไม่เป็นระเบียบ บางทีชื่อสัญลักษณ์อาจเป็นชื่อ"f_Foo"
"f_Bar_int"
อะไรก็ได้ เราต้องตรวจสอบให้แน่ใจว่าพวกเขาไม่สามารถปะทะกับชื่อที่ผู้พัฒนากำหนดไว้จริง ๆ แล้วบางทีอาจจะสำรองสัญลักษณ์ / ตัวอักษร / ระเบียบสำหรับการใช้ ABI
แต่ตอนนี้เป็นสถานการณ์ที่ยากขึ้น ตัวอย่างเช่นผู้พัฒนา Python เรียกใช้ตัวสร้างการย้ายคัดลอกตัวสร้างและ destructors อย่างไร บางทีเราสามารถส่งออกสิ่งเหล่านั้นเป็นส่วนหนึ่งของ dylib แต่จะเกิดอะไรขึ้นถ้าFoo
และBar
ส่งออกเป็นโมดูลที่แตกต่างกัน เราควรทำซ้ำสัญลักษณ์และการใช้งานที่เกี่ยวข้องใน Dylib นี้หรือไม่? ฉันขอแนะนำให้เราทำเพราะมันอาจจะน่ารำคาญจริงๆเร็วมากมิฉะนั้นจะต้องเริ่มพันกันในอินเทอร์เฟซ dylib หลาย ๆ อันเพื่อสร้างวัตถุตรงนี้ส่งผ่านตรงนี้คัดลอกที่นี่ทำลายมันที่นี่ ในขณะที่ข้อกังวลพื้นฐานเดียวกันนี้อาจนำไปใช้ใน C (ค่อนข้างมากขึ้นด้วยตนเอง / ชัดเจน), C มีแนวโน้มที่จะหลีกเลี่ยงปัญหานี้โดยธรรมชาติของวิธีที่ผู้คนเขียนโปรแกรมด้วย
นี่เป็นเพียงตัวอย่างเล็ก ๆ ของความอึดอัด จะเกิดอะไรขึ้นเมื่อหนึ่งในf
ฟังก์ชั่นด้านบนพ่น a BazException
(เช่นคลาส C ++ พร้อมคอนสตรัคเตอร์และ destructors และรับ std :: exception) ลงใน JavaScript
ที่ดีที่สุดฉันคิดว่าเราสามารถหวังว่าจะสร้างมาตรฐาน ABI ที่ทำงานจากไบนารีหนึ่งที่ผลิตโดยคอมไพเลอร์ C ++ หนึ่งไปยังไบนารีอื่นที่ผลิตโดยอีกหนึ่ง แน่นอนว่าเป็นเรื่องที่ดี แต่ฉันแค่อยากจะชี้ให้เห็น โดยทั่วไปแล้วความกังวลดังกล่าวในการแจกจ่ายไลบรารีทั่วไปที่ทำงานข้ามคอมไพเลอร์ก็มักจะเป็นความปรารถนาที่จะทำให้มันเป็นภาษาไขว้ทั่วไปและเข้ากันได้
โซลูชั่นที่แนะนำ
วิธีแก้ปัญหาที่แนะนำของฉันหลังจากดิ้นรนเพื่อหาวิธีใช้อินเทอร์เฟซ C ++ สำหรับ APIs / ABIs สำหรับปีที่มีอินเทอร์เฟซแบบ COM คือการกลายเป็นนักพัฒนา "C / C ++" (pun)
ใช้ C เพื่อสร้าง ABIs สากลที่มี C ++ สำหรับการนำไปใช้ เรายังสามารถทำสิ่งต่าง ๆ เช่นฟังก์ชั่นการส่งออกที่ส่งกลับพอยน์เตอร์ไปยังคลาส C ++ แบบทึบด้วยฟังก์ชันที่ชัดเจนเพื่อสร้างและทำลายออบเจ็กต์เหล่านี้บนฮีป ลองตกหลุมรักกับสุนทรียศาสตร์ C นั้นจากมุมมองของ ABI แม้ว่าเราจะใช้ C ++ สำหรับการนำไปใช้ทั้งหมด อินเตอร์เฟสนามธรรมสามารถสร้างแบบจำลองได้โดยใช้ตารางของตัวชี้ฟังก์ชัน เป็นเรื่องน่าเบื่อที่จะรวบรวมสิ่งนี้ไว้ใน C API แต่ข้อดีและความเข้ากันได้ของการกระจายที่มาพร้อมกับที่มีแนวโน้มที่จะทำให้มันคุ้มค่ามาก
ถ้าเราไม่ชอบใช้อินเทอร์เฟซนี้โดยตรงมาก (อย่างน้อยเราก็ไม่ควรด้วยเหตุผล RAII) เราสามารถห่อมันทั้งหมดที่เราต้องการในไลบรารี C ++ ที่ลิงก์แบบสแตติกที่เราจัดส่งด้วย SDK ลูกค้า C ++ สามารถใช้สิ่งนั้นได้
ลูกค้า Python ไม่ต้องการใช้อินเตอร์เฟส C หรือ C ++ โดยตรงเนื่องจากไม่มีวิธีในการสร้าง pythonique เหล่านั้น พวกเขาจะต้องการห่อมันไว้ในอินเทอร์เฟซของไพ ธ อนดังนั้นจึงเป็นเรื่องดีที่เราเพิ่งส่งออก C API / ABI ขั้นต่ำเปล่าเพื่อให้ง่ายที่สุด
ฉันคิดว่าอุตสาหกรรม C ++ จำนวนมากจะได้รับประโยชน์จากการทำเช่นนี้มากกว่าที่จะพยายามจัดส่งอินเทอร์เฟซแบบ COM และอื่น ๆ มันจะทำให้ทุกชีวิตของเราง่ายขึ้นเมื่อผู้ใช้ dylib เหล่านี้ไม่ต้องกังวลกับ ABIs ที่น่าอึดอัดใจ C ทำให้มันง่ายและความเรียบง่ายของมันจากมุมมองของ ABI ทำให้เราสามารถสร้าง API / ABIs ที่ทำงานได้อย่างเป็นธรรมชาติและเรียบง่ายสำหรับ FFIs ทุกประเภท