C ++: การขาดมาตรฐานในระดับไบนารี


14

เหตุใด ISO / ANSI จึงไม่ได้มาตรฐาน C ++ ที่ระดับไบนารี มีปัญหาเรื่องความสะดวกในการพกพากับ C ++ ซึ่งเป็นเพราะขาดมาตรฐานในระดับไบนารีเท่านั้น

Don Boxเขียน (อ้างจากหนังสือของเขาEssential COM , ตอนที่COM เป็น C ++ ที่ดีกว่า )

C ++ และการพกพา


เมื่อตัดสินใจที่จะทำเพื่อแจกจ่ายคลาส c ++ เป็น DLL ที่หนึ่งจะต้องเผชิญกับหนึ่งในจุดอ่อนพื้นฐานของภาษา C ++ , ที่อยู่, ขาดมาตรฐานในระดับไบนารี แม้ว่ากระดาษทำงานฉบับร่าง ISO / ANSI C ++ พยายามที่จะประมวลผลว่าโปรแกรมใดจะรวบรวมและผลกระทบทางความหมายของการเรียกใช้จะเป็นอย่างไร ครั้งแรกที่ปัญหานี้จะเห็นได้ชัดคือเมื่อไคลเอ็นต์พยายามเชื่อมโยงกับไลบรารีนำเข้าของ FastString DLL จากสภาพแวดล้อมการพัฒนา C ++ นอกเหนือจากที่ใช้ในการสร้าง FastString DLL

มีประโยชน์มากขึ้นหรือสูญเสียมาตรฐานขาดเลขฐานสองนี้หรือไม่?


นี่เป็นคำถามที่ดีกว่าในprogrammers.stackexchange.comหรือเปล่าว่ามันเป็นคำถามเชิงอัตวิสัยมากกว่านี้หรือไม่?
Stephen Furlani

1
คำถามที่เกี่ยวข้องกับเหมืองจริง ๆ : stackoverflow.com/questions/2083060/…
AraK

4
Don Box เป็นคนกระตือรือร้น ไม่สนใจเขา
John Dibling

8
ดี C ไม่ได้มาตรฐานโดย ANSI / ISO ในระดับไบนารีทั้ง; OTOH C มีพฤตินัยมาตรฐาน ABI มากกว่าทางนิตินัยอย่างใดอย่างหนึ่ง C ++ ไม่มี ABI ที่เป็นมาตรฐานเช่นนี้เนื่องจากผู้ผลิตต่างมีเป้าหมายที่แตกต่างจากการใช้งาน ตัวอย่างเช่นข้อยกเว้นใน VC ++ piggyback ด้านบนของ Windows SEH POSIX ไม่มี SEH ดังนั้นการใช้แบบจำลองนั้นจึงไม่สมเหตุสมผล (ดังนั้น G ++ และ MinGW จะไม่ใช้โมเดลนั้น)
Billy ONeal

3
ฉันเห็นว่านี่เป็นคุณสมบัติที่ไม่ใช่จุดอ่อน หากคุณผูกติดตั้งกับ ABI เฉพาะเราจะไม่มีนวัตกรรมและฮาร์ดแวร์ใหม่จะถูกผูกไว้กับการออกแบบของภาษา (และเนื่องจากมี 15 ปีระหว่างแต่ละเวอร์ชันใหม่ซึ่งเป็นเวลานานในอุตสาหกรรมฮาร์ดแวร์) และโดยการยับยั้ง คิดค้นแนวคิดใหม่ ๆ เพื่อให้โค้ดทำงานได้อย่างมีประสิทธิภาพมากขึ้นจะไม่ถูกสร้างขึ้น ราคาคือรหัสทั้งหมดในการปฏิบัติการต้องถูกสร้างโดยคอมไพเลอร์ / เวอร์ชั่นเดียวกัน (ปัญหา แต่ไม่ใช่ปัญหาหลัก)

คำตอบ:


16

ภาษาที่มีรูปแบบที่คอมไพล์ด้วยไบนารีนั้นเป็นเฟสที่ค่อนข้างใหม่ [*] ตัวอย่างเช่น JVM และ. NET runtimes คอมไพเลอร์ C และ C ++ มักจะปล่อยโค้ดเนทีฟ

ข้อได้เปรียบคือไม่จำเป็นต้องใช้ JIT หรือล่าม bytecode หรือ VM หรือสิ่งอื่นใด ตัวอย่างเช่นคุณไม่สามารถเขียนรหัส bootstrap ที่ทำงานเมื่อเริ่มต้นระบบเป็นดี by Javaode แบบพกพาเว้นแต่ว่าเครื่องสามารถดำเนินการ Java bytecode หรือคุณมีตัวแปลงบางชนิดจาก Java เป็นพื้นเมืองที่ไม่รองรับไบนารี รหัสที่ปฏิบัติการได้ (ในทางทฤษฎี: ไม่แน่ใจว่าสิ่งนี้สามารถแนะนำในทางปฏิบัติสำหรับรหัส bootstrap) คุณสามารถเขียนมันใน C ++ มากกว่าหรือน้อยกว่าแม้ว่าจะไม่ใช่พกพา C ++ แม้ในระดับที่มาเพราะมันจะยุ่งกับที่อยู่ฮาร์ดแวร์มายากล

ข้อเสียคือรหัสพื้นเมืองแน่นอนเพียงทำงานที่ทั้งหมดในสถาปัตยกรรมที่มันถูกรวบรวมและ executables เท่านั้นที่สามารถโหลดโดยรถตักดินที่เข้าใจรูปแบบปฏิบัติการของพวกเขาและเชื่อมโยงกับการโทรเข้ามาในการปฏิบัติการอื่น ๆ สำหรับสถาปัตยกรรมเดียวกันและ ABI

แม้ว่าคุณจะได้มาถึงจุดนั้นการเชื่อมโยงสองเอ็กซีคิวต์เข้าด้วยกันจะทำงานได้อย่างถูกต้องตราบใดที่: (a) คุณไม่ได้ละเมิด One Definition Rule ซึ่งง่ายต่อการทำหากคอมไพล์ด้วยคอมไพเลอร์ / ตัวเลือก / อะไรก็ตาม เช่นที่พวกเขาใช้คำจำกัดความที่แตกต่างกันของคลาสเดียวกัน (ทั้งในส่วนหัวหรือเพราะพวกเขาแต่ละเชื่อมโยงแบบคงที่กับการใช้งานที่แตกต่างกัน); และ (b) รายละเอียดการติดตั้งที่เกี่ยวข้องทั้งหมดเช่นโครงร่างโครงสร้างจะเหมือนกันตามตัวเลือกคอมไพเลอร์ที่ใช้บังคับเมื่อแต่ละคอมไพล์ถูกรวบรวม

สำหรับมาตรฐาน C ++ เพื่อกำหนดทั้งหมดนี้จะลบเสรีภาพจำนวนมากที่มีอยู่ในปัจจุบันสำหรับผู้ใช้งาน Implementers กำลังใช้เสรีภาพเหล่านั้นโดยเฉพาะอย่างยิ่งเมื่อเขียนโค้ดระดับต่ำมากใน C ++ (และ C ซึ่งมีปัญหาเดียวกัน)

ถ้าคุณต้องการเขียนบางอย่างที่ดูเหมือน C ++ สำหรับเป้าหมายแบบพกพาไบนารีจะมี C ++ / CLI ซึ่งมีเป้าหมายอยู่ที่. NET และ Mono เพื่อให้คุณสามารถรัน. NET ที่อื่นที่ไม่ใช่ Windows ได้ (หวังว่า) ฉันคิดว่ามันเป็นไปได้ที่จะชักชวนคอมไพเลอร์ของ MS เพื่อผลิตชุด CIL บริสุทธิ์ที่จะทำงานบน Mono

นอกจากนี้ยังมีสิ่งต่าง ๆ ที่สามารถทำได้ด้วยเช่น LLVM เพื่อสร้างสภาพแวดล้อม C หรือ C ++ แบบพกพาไบนารี ฉันไม่ทราบว่ามีตัวอย่างที่แพร่หลายใด ๆ ออกมา

แต่สิ่งเหล่านี้ทั้งหมดขึ้นอยู่กับการแก้ไขสิ่งต่าง ๆ มากมายที่ C ++ ขึ้นอยู่กับการนำไปใช้งาน (เช่นขนาดของประเภท) จากนั้นสภาพแวดล้อมที่เข้าใจไบนารีแบบพกพาจะต้องมีอยู่ในระบบที่ใช้รหัส การอนุญาตให้ไบนารีที่ไม่ใช่แบบพกพาทำให้ C และ C ++ สามารถไปยังที่ ๆ ไบนารีแบบพกพาไม่สามารถทำได้และนั่นเป็นสาเหตุที่มาตรฐานไม่ได้พูดอะไรเกี่ยวกับไบนารีเลย

จากนั้นบนแพลตฟอร์มใด ๆ ที่ได้รับการใช้งานมักจะยังคงไม่ได้ให้เข้ากันได้ binary ระหว่างชุดที่แตกต่างกันของตัวเลือกแม้ว่ามาตรฐานจะไม่หยุดพวกเขา ถ้า Don Box ไม่ชอบคอมไพเลอร์ของ Microsoft สามารถสร้างไบนารีที่เข้ากันไม่ได้จากแหล่งเดียวกันตามตัวเลือกของคอมไพเลอร์นั่นคือทีมคอมไพเลอร์ที่เขาต้องการบ่น ภาษา C ++ ไม่ได้ห้ามคอมไพเลอร์หรือระบบปฏิบัติการไม่ให้รายละเอียดที่จำเป็นทั้งหมดดังนั้นเมื่อคุณ จำกัด ตัวเองกับ Windows นั่นไม่ใช่ปัญหาพื้นฐานของ C ++ Microsoft เลือกที่จะไม่ทำเช่นนั้น

ความแตกต่างมักจะปรากฏเป็นอีกสิ่งหนึ่งที่คุณสามารถทำผิดพลาดและขัดข้องโปรแกรมของคุณ แต่อาจมีประโยชน์อย่างมากที่จะทำให้เกิดประสิทธิภาพระหว่างตัวอย่างเช่น debug ที่เข้ากันไม่ได้กับรุ่นที่วางจำหน่ายของ dll

[*] ฉันไม่แน่ใจว่าแนวคิดนี้ถูกประดิษฐ์ขึ้นครั้งแรกอาจเป็น 1642 หรืออะไรบางอย่าง แต่ความนิยมในปัจจุบันของพวกเขาค่อนข้างใหม่เมื่อเทียบกับเวลาที่ C ++ มุ่งมั่นที่จะตัดสินใจออกแบบที่ป้องกันไม่ให้มันกำหนดไบนารี -portability


@ Steve But C มี ABI ที่กำหนดไว้อย่างดีบน i386 และ AMD64 ดังนั้นฉันสามารถส่งตัวชี้ไปยังฟังก์ชันที่คอมไพล์โดย GCC เวอร์ชัน X ไปยังฟังก์ชันที่คอมไพล์ด้วย MSVC เวอร์ชัน Y การทำเช่นนั้นกับฟังก์ชั่น C ++ นั้นเป็นไปไม่ได้
user877329

7

ความเข้ากันได้ข้ามแพลตฟอร์มและคอมไพเลอร์ข้ามไม่ใช่เป้าหมายหลักที่อยู่เบื้องหลัง C และ C ++ พวกเขาเกิดมาในยุคหนึ่งและมีจุดประสงค์เพื่อจุดประสงค์ในการลดเวลาและพื้นที่เฉพาะของแพลตฟอร์มและเฉพาะคอมไพเลอร์

จาก Stroustrup ของ "การออกแบบและวิวัฒนาการของ C ++":

"เป้าหมายที่ชัดเจนคือการจับคู่ C ในแง่ของเวลาทำงานความกะทัดรัดของโค้ดและความกะทัดรัดของข้อมูล ... อุดมคติ - ซึ่งบรรลุผลสำเร็จ - คือ C ที่มีคลาสสามารถใช้สำหรับสิ่งที่ C สามารถใช้ได้"


1
+1 - อย่างแน่นอน เราจะสร้าง ABI มาตรฐานที่ทำงานกับกล่อง ARM และ Intel ได้อย่างไร จะไม่เข้าท่า!
Billy ONeal

1
น่าเสียดายที่มันล้มเหลวในเรื่องนี้ คุณสามารถทำทุกอย่างที่ C ทำ ... ยกเว้นโหลดโมดูล C ++ ที่รันไทม์ คุณต้อง 'เปลี่ยนกลับ' เพื่อใช้ฟังก์ชั่น C ในส่วนต่อประสานที่เปิดเผย
gbjbaanb

6

มันไม่ใช่ข้อผิดพลาดมันเป็นคุณสมบัติ! สิ่งนี้ให้อิสระแก่ผู้ใช้งานในการปรับการใช้งานให้เหมาะสมที่สุดในระดับไบนารี i386 ที่น้อยที่สุดและลูกหลานไม่ใช่ซีพียูตัวเดียวที่มีอยู่หรือมีอยู่


6

ปัญหาที่อธิบายไว้ในใบเสนอราคามีสาเหตุมาจากการหลีกเลี่ยงการวางมาตรฐานของแผนการจัดการชื่อสัญลักษณ์ (ฉันคิดว่า "มาตรฐานที่ระดับไบนารี " เป็นวลีที่ทำให้เข้าใจผิดในแง่นี้แม้ว่าปัญหาจะเกี่ยวข้องกับApplication Binaryของคอมไพเลอร์( ABI)

C ++ เข้ารหัสฟังก์ชันหรือข้อมูลลายเซ็นและชนิดข้อมูลของวัตถุและการเป็นสมาชิกคลาส / เนมสเปซในชื่อสัญลักษณ์และคอมไพเลอร์ที่แตกต่างกันได้รับอนุญาตให้ใช้ชุดรูปแบบที่แตกต่างกัน ดังนั้นสัญลักษณ์ในไลบรารีแบบคงที่, DLL หรือไฟล์วัตถุจะไม่เชื่อมโยงกับรหัสที่คอมไพล์โดยใช้คอมไพเลอร์ที่แตกต่างกัน (หรืออาจเป็นเวอร์ชั่นที่แตกต่างจากคอมไพเลอร์เดียวกัน)

ปัญหาได้รับการอธิบายและอธิบายได้ดีกว่าที่ฉันสามารถทำได้ที่นี่พร้อมตัวอย่างแผนการใช้คอมไพเลอร์ที่แตกต่างกัน

สาเหตุของการขาดเจตนาของมาตรฐานจะอธิบายยังที่นี่


3

เป้าหมายของ ISO / ANSI คือการสร้างมาตรฐานภาษา C ++ ปัญหาที่ดูเหมือนจะซับซ้อนพอที่จะต้องใช้เวลาหลายปีในการปรับปรุงมาตรฐานภาษาและการสนับสนุนคอมไพเลอร์

ความเข้ากันได้ของไบนารีนั้นซับซ้อนมากขึ้นเนื่องจากไบนารีจำเป็นต้องทำงานบนสถาปัตยกรรมของซีพียูและสภาพแวดล้อมระบบปฏิบัติการที่แตกต่างกัน


จริง แต่ปัญหาที่อธิบายไว้ในใบเสนอราคาเป็นจริงไม่เกี่ยวกับ "ความเข้ากันได้ระดับไบนารี" (แม้จะมีการใช้คำของผู้เขียน) ในแง่ใดนอกเหนือจากสิ่งที่กำหนดไว้ในสิ่งที่เรียกว่า "Application Binary Interface" ในความเป็นจริงเขาอธิบายถึงปัญหาของแผนการ mangling ชื่อที่เข้ากันไม่ได้

@Clifford: ชื่อ mangling scheme เป็นเพียงส่วนย่อยของความเข้ากันได้ระดับไบนารี หลังเป็นเหมือนร่มมากขึ้น!
นาวาซ

ฉันสงสัยว่ามีปัญหากับการพยายามใช้งานไบนารี Linux บนเครื่อง windows สิ่งต่าง ๆ จะดีขึ้นมากถ้ามี ABI ต่อแพลตฟอร์มเพราะอย่างน้อยภาษาสคริปต์สามารถโหลดและรันไบนารีบนแพลตฟอร์มเดียวกันแบบไดนามิกหรือแอปสามารถใช้ส่วนประกอบที่สร้างขึ้นด้วยคอมไพเลอร์ที่แตกต่างกัน คุณไม่สามารถใช้ C dll บน linux วันนี้และไม่มีใครบ่น แต่ C dll นั้นยังคงสามารถโหลดได้โดยแอปหลามซึ่งเป็นที่ที่ผลประโยชน์เกิดขึ้น
gbjbaanb

2

แอนดี้กล่าวว่าการทำงานร่วมกันข้ามแพลตฟอร์มไม่ได้เป็นเป้าหมายใหญ่ในขณะที่การใช้งานแพลตฟอร์มและฮาร์ดแวร์กว้างเป็นเป้าหมายโดยมีผลลัพธ์สุทธิที่คุณสามารถเขียนการใช้งานที่สอดคล้องสำหรับการเลือกระบบที่หลากหลาย การสร้างมาตรฐานให้กับไบนารี่ทำให้ไม่สามารถทำได้จริง

ความเข้ากันได้ของ C ก็มีความสำคัญและจะมีความซับซ้อนเช่นนี้

ต่อมามีความพยายามบางอย่างในการสร้างมาตรฐาน ABIให้กับชุดย่อยของการนำไปใช้งาน


ใช่ฉันลืมความเข้ากันได้ C จุดดี +1!
Andy Thomas

1

ฉันคิดว่าการขาดมาตรฐานสำหรับ C ++ เป็นปัญหาในโลกปัจจุบันของการเขียนโปรแกรมแบบแยกส่วน อย่างไรก็ตามเราต้องกำหนดสิ่งที่เราต้องการจากมาตรฐานดังกล่าว

ไม่มีใครในใจที่ถูกต้องต้องการกำหนดการนำไปใช้หรือแพลตฟอร์มสำหรับไบนารี ดังนั้นคุณไม่สามารถใช้ x86 Windows dll และเริ่มใช้บนแพลตฟอร์ม x86_64 Linux นั่นคงเป็นเรื่องเล็กน้อย

อย่างไรก็ตามสิ่งที่ผู้คนต้องการคือสิ่งเดียวกันกับที่เรามีกับโมดูล C - อินเทอร์เฟซมาตรฐานที่ระดับไบนารี (เช่นรวบรวมครั้งเดียว) ปัจจุบันหากคุณต้องการโหลด dll ในแอพแบบแยกส่วนคุณจะส่งออกฟังก์ชั่น C และผูกไว้ที่รันไทม์ คุณไม่สามารถทำได้ด้วยโมดูล C ++ มันจะดีถ้าคุณทำได้ซึ่งก็หมายความว่ากำลังที่เขียนด้วยคอมไพเลอร์หนึ่งสามารถโหลดได้โดยที่แตกต่างกัน แน่นอนว่าคุณยังคงไม่สามารถโหลด dll ที่สร้างขึ้นสำหรับแพลตฟอร์มที่เข้ากันไม่ได้ แต่นั่นไม่ใช่ปัญหาที่ต้องแก้ไข

ดังนั้นหากหน่วยมาตรฐานกำหนดว่าส่วนต่อประสานของโมดูลเปิดเผยอะไรเราจะมีความยืดหยุ่นมากขึ้นในการโหลดโมดูล C ++ เราไม่จำเป็นต้องเปิดเผยรหัส C ++ เป็นรหัส C และเราอาจใช้ประโยชน์ได้มากขึ้น ของ C ++ ในภาษาสคริปต์

นอกจากนี้เรายังไม่ต้องทนทุกข์ทรมานกับสิ่งต่างๆเช่น COM ที่พยายามจัดหาวิธีแก้ไขปัญหานี้


1
+1 ใช่ฉันเห็นด้วย คำตอบอื่น ๆ ที่นี่โดยทั่วไปแล้วจะช่วยแก้ปัญหาโดยบอกว่ามาตรฐานไบนารีจะห้ามการเพิ่มประสิทธิภาพเฉพาะสถาปัตยกรรม แต่ไม่ thats จุด. ไม่มีใครเถียงกันเรื่องรูปแบบไบนารีปฏิบัติการข้ามแพลตฟอร์ม ปัญหาคือไม่มีอินเทอร์เฟซมาตรฐานในการโหลดโมดูล C ++ แบบไดนามิก
Charles Salvia

1

มีปัญหาเรื่องความสะดวกในการพกพากับ 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 ทุกประเภท


1
"ใช้ C เพื่อสร้าง ABIs สากลเหล่านั้นด้วย C ++ สำหรับการนำไปใช้งาน" ... ฉันทำเช่นเดียวกันเหมือนคนอื่น ๆ !
นาวาซ

-1

ฉันไม่รู้ว่าทำไมมันไม่ได้มาตรฐานในระดับไบนารี แต่ฉันรู้ว่าฉันทำอะไรกับมัน ใน Windows ฉันประกาศฟังก์ชั่นภายนอก "C" BOOL WINAPI (แน่นอนแทนที่บูลด้วยประเภทของฟังก์ชั่น) และพวกมันจะถูกส่งออกอย่างสะอาด


2
แต่ถ้าคุณประกาศมันextern "C"จะใช้ C ABI ซึ่งเป็นมาตรฐานจริงในฮาร์ดแวร์พีซีทั่วไปแม้ว่าจะไม่ได้กำหนดโดยคณะกรรมการใด ๆ
Billy ONeal

-3

ใช้unzip foo.zip && make foo.exe && foo.exeหากคุณต้องการความสะดวกในการพกพาของแหล่งที่มา

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.