ฉันจะเขียนชุดฟังก์ชั่นที่สามารถเรียกใช้จาก (เกือบ) ภาษาการเขียนโปรแกรมได้อย่างไร?


33

ฉันต้องการหาวิธีเขียน API ที่สามารถเข้าถึงได้จากภาษาโปรแกรมอื่น ๆ ผ่านการเชื่อมโยงภาษา (หรือกรอบงานอื่น ๆ ) เป็นไปได้ที่จะทำเช่นนี้? ถ้าใช่ภาษาการเขียนโปรแกรมใดจะเหมาะที่สุดสำหรับการเขียน "ข้ามภาษา" API เป้าหมายของฉันคือการสร้างฟังก์ชั่นชุดเดียวที่ฉันสามารถเข้าถึงได้จากภาษาการเขียนโปรแกรมใด ๆ ที่ฉันทำงานด้วยเพื่อที่ฉันจะได้ไม่ต้องเขียน API ใหม่ทั้งหมดในแต่ละภาษาด้วยตนเอง


4
หากคุณต้องการที่จะพูดว่า "เราสนับสนุนทุกอย่าง" เพื่อเหตุผลทางการตลาดคุณสามารถเขียน DLL ระดับต่ำหรือห้องสมุดสาธารณะที่ใช้ร่วมกันใน C. หากคุณต้องการให้ใครพูด Java ใช้สิ่งที่คุณต้องการ จัดเตรียมอินเตอร์เฟส Java ให้ดีขึ้น
mjfgates

1
คุณพูดว่า "(เกือบ) ใด ๆ " คุณจะยกเว้นภาษาใดในวัตถุประสงค์นี้ หรือสิ่งใดที่สำคัญที่สุดสำหรับคุณ
funkybro

22
บริการเว็บ? คุณสามารถเขียนฟังก์ชั่นบางอย่างใน php เช่น เกือบทุกภาษามีความเป็นไปได้ที่จะเชื่อมต่อกับหน้าเว็บจัดหาข้อโต้แย้งและอ่านผลลัพธ์
Pieter B

7
+1 เพราะเป็นคำถามที่น่าสนใจ แต่คำถามของคุณจะได้รับการปรับปรุงโดยบอกว่าทำไมคุณถึงต้องการทำสิ่งนี้ เป้าหมายของคุณคืออะไร
TarkaDaal

@PieterB => คำตอบ
Konrad Rudolph

คำตอบ:


44

คุณมีตัวเลือกน้อย:

  1. สร้างส่วนต่อประสาน HTTP เกือบทุกอย่างสามารถพูดคุยกับ HTTP เพื่อให้คุณได้รับภาษามากมาย

  2. สร้างบางสิ่งที่สามารถเชื่อมโยงกับรันไทม์ภาษาซึ่งจะใช้เวลาค่อนข้างนานเนื่องจากคุณจะต้องหาวิธีในการเชื่อมต่อกับหลายภาษา


คุณคิดว่ามีอินเตอร์เฟส HTTP ชนิดใดเป็นพิเศษ?
Anderson Green

@AndersonGreen มันไม่สำคัญ (เนื่องจากภาษาใด ๆ ที่สามารถเปิดซ็อกเก็ตเครือข่ายสามารถพูด HTTP ได้) แต่RESTนั้นเป็นมาตรฐานหลอกที่มีประโยชน์
Reinstate Monica

7
REST + JSON จะเป็นคำตอบที่สมเหตุสมผล
David Hayes

ฉันเห็นด้วยเช่นกันการใช้ HTTP เพื่อสื่อสารทำให้ทุกภาษามีปฏิสัมพันธ์กับฟังก์ชันของแอปพลิเคชัน
เฉพาะชาวโบลิเวียที่นี่

30

ฉันคิดว่า C หรือ C ++ จะเหมาะสมที่สุดสำหรับวัตถุประสงค์ของคุณ คุณสามารถใช้SWIG (Simplified Wrapper และ Interface Generator)เพื่อสร้างการเชื่อมภาษาจาก C หรือ C ++ API ของคุณ

SWIG เป็นเครื่องมือพัฒนาซอฟต์แวร์ที่เชื่อมต่อโปรแกรมที่เขียนด้วย C และ C ++ กับภาษาการเขียนโปรแกรมระดับสูงที่หลากหลาย SWIG ใช้กับภาษาเป้าหมายประเภทต่าง ๆ รวมถึงภาษาสคริปต์ทั่วไปเช่น Perl, PHP, Python, Tcl และ Ruby รายการภาษาที่รองรับยังมีภาษาที่ไม่ใช่สคริปต์เช่น C #, Common LISP (CLISP, Allegro CL, CFFI, UFFI), D, Go language, Java รวมถึง Android, Lua, Modula-3, OCAML, Octave และ R รองรับการใช้งาน (Guile, MzScheme / Racket, Chicken) SWIG มักใช้ในการสร้างสภาพแวดล้อมการเขียนโปรแกรมระดับสูงตีความหรือรวบรวมส่วนติดต่อผู้ใช้และเป็นเครื่องมือสำหรับการทดสอบและการสร้างต้นแบบซอฟต์แวร์ C / C ++ โดยทั่วไปจะใช้ SWIG ในการแยกวิเคราะห์อินเตอร์เฟส C / C ++ และสร้าง 'รหัสกาว' ที่จำเป็นสำหรับภาษาเป้าหมายข้างต้นเพื่อเรียกใช้รหัส C / C ++ SWIG ยังสามารถส่งออกแผนภูมิการแยกวิเคราะห์ในรูปแบบของ XML และ Lisp s-expressions SWIG เป็นซอฟต์แวร์ฟรีและรหัสที่ SWIG สร้างนั้นเข้ากันได้กับโครงการเชิงพาณิชย์และไม่ใช่เชิงพาณิชย์ ...


32
C ++ จะเป็นตัวเลือกที่น่ากลัว มีปัญหามากมายกับมัน: การพึ่งพาไลบรารีรันไทม์, ABI ที่ไม่ระบุ (โดยเฉพาะอย่างยิ่ง mangling), ฯลฯ การสร้างการเชื่อมจากส่วนหัวของ C ++ นั้นเป็นเรื่องยุ่งยาก SWIG ค่อนข้าง จำกัด ดูโครงสร้างพื้นฐานที่ซับซ้อนรอบตัวพูด Python Qt การเชื่อมโยง
SK-logic

14
@ SK-logic: ไม่จริง C ต้องการ lib แบบรันไทม์เช่นเดียวกับ C ++ ABI สามารถควบคุมได้ใน C ++ ผ่านextern "C"ดังนั้นมันจึงเข้ากันได้กับ C ภายนอก ดังนั้นคุณจะมีข้อได้เปรียบภายในของ C ++ (ความปลอดภัยประเภทที่สูงขึ้น, ห้องสมุด) แต่ข้อดีภายนอกของ C (มาตรฐานพฤตินัย ABI)
MSalters

3
@ SK-logic ABI ที่ไม่ระบุเป็นเพียงปัญหาที่แก้ไขแล้วให้ดู SWIG, Boost.Python และโฮสต์ของการเชื่อมภาษาอื่น ๆ
Konrad Rudolph

3
@MSalters อย่าลืมข้อยกเว้นและความไม่สะดวกทั่วไปในขอบเขตห้องสมุด
sehe

3
-1 สำหรับข้อเสนอแนะ C ++ C นั้นง่าย C ++ ทำให้ทุกอย่างเป็นเรื่องยาก
Ernest Friedman-Hill

23

มี 2 ​​วิธีที่สวยมาก:

  • C API แทบจะไม่เคยมีภาษาที่เคยโหลดห้องสมุด C และเรียกฟังก์ชั่นของมัน วิธีที่คุณทำสิ่งนี้ขึ้นอยู่กับภาษาต้นฉบับ
  • กลไก RPC ของการเรียงลำดับบางอย่าง นี่อาจเป็น REST API ที่รันบน HTTP หรืออินเตอร์เฟสไบนารีที่รันบนซ็อกเก็ต ถ้าคุณไม่ใช้กลไกตัวหารร่วมที่ต่ำที่สุด (เช่นซ็อกเก็ต) คุณจะเสี่ยงต่อการไม่มีรูทีนการเข้าถึงไคลเอ็นต์ (เช่นบางภาษาไม่มีไคลเอ็นต์ SOAP ที่เหมาะสมที่จะเรียกใช้ API ที่ใช้ SOAP หรือมีปัญหาการทำงานร่วมกัน) ติดกับอินเตอร์เฟส HTTP / REST ที่ง่ายที่สุดหรือซ็อกเก็ต Sockets มีข้อได้เปรียบที่พวกเขาไม่ต้องการเซิร์ฟเวอร์ HTTP เพื่อเปิดเผยอินเตอร์เฟสกับไคลเอ็นต์และสามารถรันบนเซิร์ฟเวอร์เดียวกันกับไคลเอ็นต์ที่มีประสิทธิภาพดีขึ้นได้ง่ายขึ้น

งานที่ต้องการสำหรับการเปลี่ยนแปลงนี้ขึ้นอยู่กับระบบที่ใช้ตัวอย่างเช่นอินเตอร์เฟสซ็อกเก็ตจะทำงานได้ แต่ไลบรารีฝั่งไคลเอ็นต์มักจะมีระดับต่ำกว่าเมื่อเปรียบเทียบกับไลบรารี HTTP

คุณสามารถลองค้นหาห้องสมุดเครือข่ายที่รองรับทุกภาษาที่คุณต้องการและใช้ API ในแง่ของห้องสมุดนั้น - เช่นการใช้ ZeroMQ ให้ความยืดหยุ่นแก่คุณมากดังนั้นคุณจึงต้องเขียน API ของคุณโดยใช้อินเตอร์เฟส ZeroMQ และ ดังนั้นภาษาใด ๆ ที่ต้องการเรียก API ของคุณจะต้องใช้ไลบรารี่ ZeroMQ เพื่อทำเช่นนั้น เลือกไลบรารีที่รองรับภาษาที่หลากหลายและช่วยให้คุณสามารถทำการสื่อสารระหว่างดำเนินการและประมวลผลเพื่อประสิทธิภาพที่ดีที่สุด


ดังนั้นฉันจะต้องทำขั้นตอนใดถ้าฉันต้องการเขียน API ในหลายภาษาเช่นกัน? (ในกรณีของฉันภาษาเหล่านั้นจะเป็น Javascript, C ++ และ Java)
Anderson Green

ฉันควรเขียน RESTful API แยก 3 ตัวสำหรับแต่ละภาษาหรือไม่
Anderson Green

คุณเขียน wrapper ดั้งเดิมในแต่ละภาษาเหล่านี้ที่จัดการการโหลดและการเรียก dll C พื้นฐาน หรือเขียนใน C ++ และใช้ SWIG เพื่อทำสิ่งนี้ให้คุณ หากคุณใช้ REST API ก็จะมีผลเช่นเดียวกันเขียนทั้ง API เดียวแล้วเลือก 3 ตัว แต่ถ้าคุณเขียน REST API แล้วแต่ละภาษาจะสามารถเรียก REST API ได้โดยตรงไม่ต้องกังวล ด้วยเสื้อคลุม
gbjbaanb

dll (ไลบรารีที่ลิงก์แบบไดนามิก) จะเข้ากันได้กับแพลตฟอร์มใด ๆ นอกเหนือจาก Windows หรือไม่ ฉันต้องการความเข้ากันได้ข้ามแพลตฟอร์มที่นี่
Anderson Green

ไม่คุณต้องรวบรวมใหม่สำหรับแพลตฟอร์มอื่น ๆ Linux ใช้ตัวอย่างเช่น. so แทนที่จะเป็น. dll ต้องการคอมไพล์ซ้ำโดยตรงไม่มีการเปลี่ยนแปลงรหัส (หรือน้อยมาก)
gbjbaanb

12

หากประสิทธิภาพและการหน่วงเวลาการโทรไม่ใช่ปัญหาให้พิจารณาจัดเตรียมอินเตอร์เฟสบรรทัดคำสั่งที่ครอบคลุม (อาจใช้ภาษาสคริปต์ด้านบน) ImageMagick เป็นตัวอย่างที่ดีของ "API" อีกตัวอย่างที่ดีคือชุดเครื่องมือ Tk


ภาษาสคริปต์และ / หรือภาษาการเขียนโปรแกรมใดที่คุณจะแนะนำสำหรับวัตถุประสงค์ในการสร้างอินเตอร์เฟสบรรทัดคำสั่งฟังก์ชันต่างประเทศ นอกจากนี้คุณได้พบตัวอย่างที่เป็นรูปธรรมของอินเทอร์เฟซดังกล่าวหรือไม่
Anderson Green

@AndersonGreen ภาษาใด ๆ ที่มี metaprogramming ที่ดีนั้นก็โอเคสำหรับวัตถุประสงค์ดังกล่าว เช่น Scheme, MetaLua, Lisps แบบฝังอื่น ๆ ที่หลากหลาย, Tcl คุณสามารถใช้ภาษาคำสั่งของคุณเองได้อย่างง่ายดายเช่นกัน ระบบ CAD / CAE จำนวนมากทำงานด้วยวิธีนี้ Tk ที่กล่าวถึงแล้วเป็นอีกตัวอย่างทั่วไป
SK-logic

ในการใช้อินเตอร์เฟสบรรทัดคำสั่งด้วยวิธีนี้คุณจะได้รับเอาต์พุตคอนโซลสำหรับคำสั่งเฉพาะ (เช่นwhoamiบน Ubuntu เพื่อรับชื่อผู้ใช้) หรือคุณมีสิ่งอื่นในใจหรือไม่
Anderson Green

@AndersonGreen ท่อ stdin และ stdout น่าจะเพียงพอในกรณีส่วนใหญ่
SK-logic

5

โดย API คุณหมายถึงอะไรอย่างแท้จริง

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

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

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

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


2

เพื่อเพิ่มคำตอบข้างต้นที่แนะนำให้ใช้กลไก RPC คุณสามารถใช้ Apache Thrift ได้ ( http://thrift.apache.org/ ) มันเป็นพื้น RPC

ตามวิกิ:

เฟรมเวิร์กซอฟต์แวร์ Apache Thrift สำหรับการพัฒนาบริการข้ามภาษาสามารถรวมซอฟต์แวร์สแต็คเข้ากับเอ็นจินการสร้างรหัสเพื่อสร้างบริการที่ทำงานอย่างมีประสิทธิภาพและต่อเนื่องระหว่าง C ++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C # Cocoa, JavaScript, Node.js, Smalltalk, OCaml และ Delphi และภาษาอื่น ๆ


การเรียกฟังก์ชั่นต่างประเทศสามารถทำได้โดยใช้ Apache Thrift ได้อย่างไร
Anderson Green

0

ให้ภาษาใด ๆ เขียนไฟล์ข้อความที่มีฟังก์ชั่นโทรหาด้วย params เพื่อส่งผ่านมีแอพ "ฉันเข้ากับใครก็ได้" ดูไดเรกทอรีและเมื่อมันเห็น process-call.txt ทำงานแล้ว ไม่มีเซิร์ฟเวอร์หรือโปรโตคอลเครือข่าย แม้แต่วิธีการใช้ภาษาที่ไม่ใช่คอมพิวเตอร์ก็สามารถใช้งานได้ แม้แต่บุคคลก็สามารถสร้างไฟล์ข้อความได้

เนื้อหาอาจมีลักษณะ:

Call-method:  fdisk()
Params:  (string) "/root", (string) "write-back-file-expected.txt"

;) คุณอาจรอตลอดไปเพื่อรับคำตอบ คุณต้องกดสองสามไบต์ไปที่กระบวนการอื่น แต่ฉันแน่ใจว่านั่นไม่ใช่สเปคทั้งหมด


ดูเหมือนซับซ้อนเกินไปเมื่อคุณเพิ่งมี command-line interface + stdin / stdout
Reinstate Monica

1
การโทรที่ดียิ่งขึ้นสามารถ ++ 1 ได้นั่นคือเบรนแดน ฉันไม่เคยเห็นมันทำงาน แต่ครั้งหนึ่งมีคนเจาะรูในการ์ดเพื่อถ่ายโอนไบต์รอบ ๆ
Pareshkumar

4
นี่เป็นคำตอบที่ตลกใช่มั้ย เราไม่ทำอย่างนั้น
Ernest Friedman-Hill

ส่วน fdisk และ / root เป็นเรื่องตลก แต่ฉันเกี่ยวข้องกับแพลตฟอร์ม r & d (นักพัฒนาและนักวิเคราะห์) มานานกว่า 5 ปีเพื่อสร้างผลิตภัณฑ์แพลตฟอร์มที่ผลิตได้ดีในราคา 10 ล้านดอลลาร์ มันแยกรายการทางกายภาพออกเป็นล้านรายการ (ไม่ใช่ pdf และอีเมล) สำหรับลูกค้า (ด้วยการประมวลผลไฟล์ที่มีหลายร้อย MB ต่อรายการ) โดยใช้วิธีการ REST ประเภทนี้ เรามีระบบหลัก triolgy-SAP-MS Office-PLC Drivewrs-PDF เวิร์กโฟลว์ทั้งหมดที่พากันทำงานร่วมกันได้ดีกับไฟล์ UTF-8-text แบบธรรมดาและ zip พร้อมซิปใน - มีซิป และไม่มีค่าใช้จ่าย HTTP bs
Pareshkumar

ฉันขอถามสักคำได้ไหม? ทำไมไม่มีใครคิดว่า JSON เป็นเรื่องตลก? ฉันแนะนำสิ่งที่แตกต่างอย่างไร เราอาจ / อาจใช้ json แต่ไม่ได้อยู่ในปี 2003 XML นั้นอ้วนเกินไป แต่หลังจากนั้นนั่นก็คือรสชาติของเดือนไม่ใช่จิตวิญญาณที่ง่ายและสะดวกสบายที่สุด
Pareshkumar

0

OpenGL เป็นตัวอย่างที่ดีของสิ่งที่คุณอธิบาย - เป็น API ที่เขียนใน C ออกแบบมาในวิธีที่ง่ายต่อการเขียนการเชื่อมสำหรับภาษาอื่น

  1. ไลบรารี C สามารถเรียกได้จากภาษาการเขียนโปรแกรมส่วนใหญ่ (โดยปกติจะเป็นส่วนขยายที่รวบรวมหรือสิ่งต่าง ๆ เช่นctypesไลบรารีของ PyPy เป็นต้น)

  2. ฟังก์ชั่นทั้งหมดใช้ประเภทข้อมูลแบบง่าย ๆ เป็นอาร์กิวเมนต์ (บูลีน, จำนวนเต็ม, ทศนิยม, ค่าคงที่, อาร์เรย์) เนื่องจากฟังก์ชั่นที่ใช้พอยน์เตอร์สามารถแปลได้บางภาษา

  3. มีประเภทข้อมูลตัวเลขของตัวเองซึ่งระบุความแม่นยำและการเซ็นชื่อ (ในขณะที่int floatอื่น ๆ อาจแตกต่างกัน)

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

ด้านบนของ verbose API นี้คุณสามารถเขียนคำว่า "เป็นมิตรกับนักพัฒนา" เพิ่มเติมรอบนี้ (กรอบเกมและอื่น ๆ )

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