Bagaimana saya bisa menulis serangkaian fungsi yang dapat dipanggil dari (hampir) bahasa pemrograman apa pun?

33

Saya ingin menemukan cara untuk menulis API yang dapat diakses dari bahasa pemrograman lain melalui binding bahasa (atau kerangka kerja lain). Apakah mungkin untuk melakukan ini? Jika demikian, bahasa pemrograman mana yang paling cocok untuk menulis "lintas-bahasa" API? Tujuan saya adalah membuat satu set fungsi yang dapat saya akses dari bahasa pemrograman apa pun yang saya gunakan, sehingga saya tidak perlu menulis ulang seluruh API secara manual dalam setiap bahasa.

Anderson Green
sumber
4
Jika Anda hanya ingin dapat mengatakan "kami mendukung SEMUANYA" untuk alasan pemasaran, Anda bisa menulis DLL tingkat rendah atau berbagi perpustakaan di C. Jika Anda ingin seseorang di katakan, Jawa, untuk menggunakan barang Anda, Anda akan lebih baik menyediakan antarmuka Java.
mjfgates
1
Anda mengatakan "(hampir) ada", bahasa apa yang akan Anda kecualikan untuk tujuan ini? Atau mana yang paling penting bagi Anda?
funkybro
22
Layanan web? Anda dapat menulis beberapa fungsi misalnya php. Hampir semua bahasa memiliki kemungkinan untuk berinteraksi dengan halaman web, menyediakan argumen dan membaca hasilnya.
Pieter B
7
+1 karena ini adalah pertanyaan yang menarik - tetapi pertanyaan Anda akan ditingkatkan dengan mengatakan mengapa Anda ingin melakukan ini. Apa tujuanmu?
TarkaDaal
@PieterB => jawaban.
Konrad Rudolph

Jawaban:

44

Anda punya beberapa pilihan:

  1. Buat antarmuka HTTP, hampir semuanya dapat berbicara HTTP sehingga akan membuat Anda banyak bahasa.

  2. Buat sesuatu yang dapat dihubungkan ke runtime bahasa, ini akan memakan waktu karena Anda perlu menemukan cara untuk menghubungkannya ke berbagai bahasa.

Zachary K
sumber
Apa jenis antarmuka HTTP yang ada dalam pikiran Anda, khususnya?
Anderson Green
@AndersonGreen Tidak masalah (karena bahasa apa pun yang dapat membuka soket jaringan dapat berbicara HTTP), tetapi REST adalah pseudo-standar yang berguna.
Pasang kembali Monica
7
REST + JSON akan menjadi solusi yang masuk akal
David Hayes
Saya juga setuju, menggunakan HTTP untuk berkomunikasi memungkinkan hampir semua bahasa di luar sana untuk berinteraksi dengan fungsi aplikasi Anda.
Hanya Bolivia Di Sini
30

Saya pikir C atau C ++ akan paling cocok untuk tujuan Anda. Anda dapat menggunakan SWIG (Pembungkus Sederhana dan Penghasil Antarmuka) untuk menghasilkan binding bahasa dari API C atau C ++ Anda.

SWIG adalah alat pengembangan perangkat lunak yang menghubungkan program yang ditulis dalam C dan C ++ dengan berbagai bahasa pemrograman tingkat tinggi. SWIG digunakan dengan berbagai jenis bahasa target termasuk bahasa scripting umum seperti Perl, PHP, Python, Tcl dan Ruby. Daftar bahasa yang didukungjuga termasuk bahasa non-skrip seperti C #, Common Lisp (CLISP, Allegro CL, CFFI, UFFI), D, Bahasa Go, Java termasuk Android, Lua, Modula-3, OCAML, Octave dan R. Juga beberapa Skema yang ditafsirkan dan dikompilasi implementasi (Guile, MzScheme / Racket, Chicken) didukung. SWIG paling umum digunakan untuk membuat lingkungan pemrograman tingkat tinggi yang ditafsirkan atau dikompilasi, antarmuka pengguna, dan sebagai alat untuk menguji dan membuat prototipe perangkat lunak C / C ++. SWIG biasanya digunakan untuk mem-parsing antarmuka C / C ++ dan menghasilkan 'kode lem' yang diperlukan untuk bahasa target di atas untuk memanggil kode C / C ++. SWIG juga dapat mengekspor parse tree dalam bentuk ekspresi XML dan Lisp. SWIG adalah perangkat lunak gratis dan kode yang dihasilkan SWIG kompatibel dengan proyek komersial dan non-komersial ...

LMC
sumber
32
C ++ akan menjadi pilihan yang buruk. Ada banyak masalah dengan itu: ketergantungan pada pustaka runtime, ABI yang tidak ditentukan (terutama mangling), dll. Menghasilkan binding dari header C ++ sangat rumit. SWIG adalah hal yang sangat terbatas. Lihat semua infrastruktur yang terlalu rumit di sekitar, katakanlah, Python Qt bindings.
SK-logic
14
@ SK-logic: Tidak juga. C membutuhkan lib runtime seperti C ++. ABI dapat dikontrol dalam C ++ via extern "C"sehingga kompatibel dengan C di luar. Oleh karena itu, Anda memang memiliki keunggulan internal C ++ (keamanan tipe-lebih tinggi, perpustakaan) tetapi keunggulan eksternal C (standar ABI de facto)
MSalters
3
@ SK-logic ABI yang tidak ditentukan hanyalah masalah yang dipecahkan, lihat SWIG, Boost.Python dan sejumlah binding bahasa lainnya.
Konrad Rudolph
3
@MSalters jangan lupa tentang pengecualian dan ketidak-nyamanan umum mereka melintasi batas
lihat
3
-1 untuk saran C ++. C itu mudah, C ++ membuat hal-hal menjadi sulit.
Ernest Friedman-Hill
23

Ada cukup banyak 2 cara:

  • API C. Praktis bahasa yang pernah ada akan memuat pustaka C dan memanggil fungsinya. Bagaimana Anda melakukan ini tergantung pada bahasa sumber.
  • semacam mekanisme RPC. Ini bisa berupa REST API yang berjalan di HTTP, atau antarmuka biner yang berjalan di soket. Kecuali Anda menggunakan mekanisme common denominator terendah (mis. Soket) Anda berisiko tidak memiliki rutinitas akses klien (mis. Beberapa bahasa tidak memiliki klien SOAP yang tepat untuk memanggil API yang diimplementasikan menggunakan SOAP, atau ada masalah interoperabilitas). Tetap berpegang pada yang paling sederhana, baik antarmuka HTTP / REST, atau soket. Soket memiliki keuntungan karena mereka tidak memerlukan server HTTP untuk mengekspos antarmuka ke klien, dan dapat lebih mudah berjalan di server yang sama dengan klien dengan kinerja yang lebih baik.

Pekerjaan yang diperlukan untuk perubahan ini tergantung pada sistem yang digunakan, misalnya, antarmuka soket akan berfungsi, tetapi pustaka sisi klien cenderung lebih rendah daripada pustaka http.

Anda bisa mencoba menemukan pustaka jaringan yang mendukung semua bahasa yang ingin Anda gunakan, dan mengimplementasikan API dalam hal pustaka itu - misalnya, menggunakan ZeroMQ memberi Anda banyak fleksibilitas, sehingga Anda akan menulis API Anda menggunakan antarmuka ZeroMQ, dan maka bahasa apa pun yang ingin memanggil API Anda harus menggunakan pustaka klien ZeroMQ untuk melakukannya. Pilih perpustakaan yang mendukung berbagai bahasa, dan memungkinkan Anda untuk berkomunikasi dalam proses maupun di luar proses untuk kinerja terbaik.

gbjbaanb
sumber
Jadi langkah apa yang harus saya ambil jika saya ingin menulis API dalam banyak bahasa juga? (Dalam kasus saya, bahasa-bahasa itu adalah Javascript, C ++, dan Java.)
Anderson Green
Haruskah saya menulis 3 API ISTIRAH untuk masing-masing bahasa?
Anderson Green
Anda menulis pembungkus asli di masing-masing bahasa ini yang menangani pemuatan dan memanggil dll C yang mendasarinya. Atau tulis di C ++ dan gunakan SWIG untuk melakukan ini untuk Anda. Jika Anda menggunakan REST API, maka hal yang sama berlaku, baik menulis satu API dan kemudian 3 pembungkus, tetapi jika Anda menulis REST API maka setiap bahasa akan dapat memanggil REST API secara langsung - jangan repot-repot dengan pembungkus.
gbjbaanb
Apakah dll (perpustakaan yang terhubung secara dinamis) kompatibel dengan platform apa pun selain Windows? Saya perlu kompatibilitas lintas platform di sini.
Anderson Green
tidak, Anda perlu mengkompilasi ulang untuk platform lain. Linux misalnya menggunakan .so, bukan .dll. Hanya diperlukan kompilasi ulang secara langsung, tidak ada perubahan kode (atau sangat kecil).
gbjbaanb
12

Jika latensi kinerja dan panggilan bukan masalah, pertimbangkan untuk menyediakan antarmuka baris perintah yang komprehensif (mungkin, menggunakan bahasa skrip di atasnya). ImageMagick bisa menjadi contoh yang bagus untuk "API" semacam itu. Contoh bagus lainnya adalah Tk toolkit.

Logika SK
sumber
Bahasa scripting dan / atau bahasa pemrograman mana yang akan Anda rekomendasikan untuk tujuan membuat antarmuka fungsi asing baris perintah? Juga, sudahkah Anda menemukan contoh konkret antarmuka seperti itu?
Anderson Green
@AndersonGreen, bahasa apa pun dengan pemrograman yang layak tidak masalah untuk tujuan tersebut. Misalnya, Skema, MetaLua, berbagai Lisps yang dapat diembed lainnya, Tcl. Anda dapat dengan mudah mengimplementasikan bahasa perintah Anda sendiri juga. Banyak sistem CAD / CAE beroperasi dengan cara ini. Tk yang telah disebutkan adalah contoh khas lainnya.
SK-logic
Untuk menggunakan antarmuka baris perintah dengan cara ini, apakah Anda akan mendapatkan output konsol untuk perintah tertentu (seperti whoamipada Ubuntu untuk mendapatkan nama pengguna), atau apakah Anda memiliki sesuatu yang lain dalam pikiran?
Anderson Green
@AndersonGreen, stdin dan stdout perpipaan harus memadai dalam kebanyakan kasus.
SK-logic
5

Dengan API, apa sebenarnya yang Anda maksud?

Pada banyak platform Anda dapat menautkan ke DLL atau konstruksi serupa, tetapi apakah harus dikompilasi ulang untuk target asli tertentu (Intel / ARM) atau endianness masih memenuhi syarat? Antarmuka biner tertentu mungkin masih mengalami kesulitan dengan bahasa tertentu karena masalah tipe data atau konstruksi (petunjuk yang berusaha dikembalikan ke bahasa yang tidak mendukungnya dengan baik), jadi Anda juga harus mempertimbangkan desain API itu sendiri agar tidak untuk mengecualikan beberapa bahasa atau menggunakannya dari bahasa-bahasa yang rumit.

Sesuatu yang portabel seperti C dan antarmuka yang didasarkan pada titik akhir biner dalam DLL mungkin baik dan umumnya dapat dipanggil pada sebagian besar platform dan dari sebagian besar bahasa, tetapi mungkin perlu dikompilasi secara berbeda dan / atau ditawarkan dalam berbagai rasa atau dihubungkan ke perpustakaan statis yang berbeda.

Tampaknya bagi saya bahwa pilihan bahasa yang Anda tulis di perpustakaan atau layanan Anda atau apa pun, menurut definisi, tidak intrinsik dengan pertanyaan sampai Anda telah memberikan lebih banyak tentang platform / layanan yang diungkapkan oleh API. Jika Anda dapat mengasumsikan bahwa tumpukan jaringan tersedia dan kinerja fungsi-panggilan-tingkat-taut-langsung bukanlah persyaratan, API dapat dengan mudah berbasis HTTP dengan semacam shim untuk bahasa klien untuk membuat permintaan transparan.

Saya pikir secara umum pertanyaan ini terlalu luas untuk berguna di dunia nyata, karena Anda belum memberikan indikasi tentang jenis API apa yang cocok dengan jenis layanan yang ditawarkan.

Cade Roux
sumber
2

Untuk menambahkan jawaban di atas yang menyarankan menggunakan mekanisme RPC. Anda dapat menggunakan Apache Thrift. ( Http://thrift.apache.org/ ). Ini pada dasarnya adalah kerangka kerja RPC.

Sesuai wiki hemat:

Kerangka kerja perangkat lunak Apache Thrift, untuk pengembangan layanan lintas-bahasa yang dapat diskalakan, menggabungkan tumpukan perangkat lunak dengan mesin pembuatan kode untuk membangun layanan yang bekerja secara efisien dan mulus antara C ++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C #, Kakao, JavaScript, Node.js, Smalltalk, OCaml, dan Delphi serta bahasa lainnya

gt5050
sumber
Bagaimana panggilan fungsi asing dapat dilakukan menggunakan Apache Thrift?
Anderson Green
0

Mintalah bahasa apa pun menulis file teks dengan fungsi untuk memanggil dengan params untuk lulus. Buat aplikasi "Saya bergaul dengan siapa pun" menonton direktori dan begitu ia melihat proses-panggilan.txt sudah mulai berfungsi. Tidak ada server atau protokol jaringan; bahkan metode bahasa non-komputer dapat init fungsi. Bahkan seseorang bisa saja membuat file teks.

Konten dapat terlihat seperti:

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

;) Anda mungkin menunggu selamanya untuk mendapatkan jawaban. Anda hanya perlu mendorong beberapa byte ke proses lainnya, tapi saya yakin itu bukan keseluruhan spek.

Pareshkumar
sumber
Tampaknya terlalu rumit ketika Anda hanya bisa memiliki antarmuka baris perintah + stdin / stdout.
Pasang kembali Monica
1
Panggilan yang lebih baik bisa ++ 1 itu, Brendan. Saya tidak pernah melihatnya beraksi tetapi pada suatu waktu orang-orang meninju lubang untuk mentransfer byte di sekitar.
Pareshkumar
4
Ini adalah jawaban lelucon, bukan? Kami tidak melakukannya di sini.
Ernest Friedman-Hill
Yah bagian fdisk dan / root adalah lelucon, tetapi saya terlibat sebagai platform r & d (pengembang dan analis) selama lebih dari 5 tahun untuk menciptakan platform-produk yang diproduksi dengan baik dalam 10 juta dolar. Ini memuntahkan jutaan item fisik shippable (bukan pdf dan email) untuk klien (dengan memproses File berkisar ratusan MB per item) menggunakan jenis metode REST ini. Kami memiliki sistem utama triolgy-SAP-MS Office-PLC Drivewrs-Workflow PDF semua mengambil satu sama lain dan bekerja dengan baik bersama-sama dengan file-file UTF-8-teks biasa dan zip dengan-in zip dengan-in zip, dan tidak ada HTTP bs overhead.
Pareshkumar
Bolehkah saya mengajukan pertanyaan? Mengapa tidak ada yang berpikir bahwa JSON adalah lelucon? Bagaimana apa yang saya rekomendasikan berbeda? Kami akan / mungkin menggunakan json tetapi tidak ada pada tahun 2003. XML terlalu gemuk, tapi saat itu rasanya bukan bulan yang paling praktis dan paling sederhana.
Pareshkumar
0

OpenGL adalah contoh yang baik dari apa yang Anda gambarkan - ini adalah API yang ditulis dalam C, dirancang dengan cara yang mudah untuk menulis binding dalam bahasa lain

  1. Pustaka C dapat dipanggil dari sebagian besar bahasa pemrograman (biasanya sebagai ekstensi yang dikompilasi, atau hal-hal seperti ctypespustaka PyPy dll)

  2. Semua fungsi menggunakan tipe data sederhana sebagai argumen (boolean, integer, floating point, konstanta, array), karena fungsi yang mengambil pointer dapat menjadi canggung untuk diterjemahkan ke dalam beberapa bahasa

  3. Memiliki tipe data numeriknya sendiri, yang menentukan ketelitian dan kemampuan bertanda (sedangkan int floatdll dapat berbeda)

API yang dihasilkan belum tentu API C terbaik yang dapat digunakan yang bisa Anda tulis jika hanya menargetkan pengguna C. Namun itu berarti fungsi-fungsinya dapat langsung diekspos ke bahasa lain (mis. Dokumen PyOpenGL membuat daftar perbedaan, yang sebagian besar sangat minim)

Di atas API verbose ini, Anda dapat menulis lebih banyak pembungkus "ramah pengembang" di sekitar ini (kerangka permainan dan semacamnya)

dbr
sumber