Neredeyse herhangi bir programlama dilinden çağrılabilecek bir fonksiyonlar kümesini nasıl yazabilirim?


33

Dil bağlamaları (veya başka bir çerçeve) aracılığıyla başka herhangi bir programlama dilden erişilebilecek bir API yazmak için bir yol bulmak istiyorum. Bunu yapmak mümkün mü? Öyleyse, "programlama dili" API'sini yazmak için en uygun programlama dili hangisidir? Amacım, üzerinde çalıştığım herhangi bir programlama diline erişebileceğim tek bir fonksiyon seti oluşturmak ve böylece tüm API'yi her dilde manuel olarak tekrar yazmaya gerek kalmaması.


4
Pazarlama nedenleriyle sadece "HER ŞEYİ destekliyoruz" diyebilmek istiyorsanız, C'ye düşük seviyeli bir DLL veya paylaşılan bir kütüphane yazabilirsiniz. Java arayüzü sağlamak daha iyi.
mjfgates

1
“(Neredeyse) herhangi biri” dersiniz, bu amaç için hangi dilleri hariç tutacaksınız? Ya da sizin için en önemliler hangileri?
funkybro

22
İnternet servisi? Bazı fonksiyonları örneğin php ile yazabilirsiniz. Hemen hemen her dilin web sayfalarıyla arayüz oluşturma, tartışmalar yapma ve sonuçları okuma imkanı vardır.
Pieter B

7
+1 'çünkü bu ilginç bir soru - ancak sorunuzu neden yapmak istediğinizi söyleyerek daha iyi hale geleceksiniz. Hedeflerin ne?
TarkaDaal

@ PieterB => cevap.
Konrad Rudolph

Yanıtlar:


44

Birkaç seçeneğiniz var:

  1. Bir HTTP arayüzü oluşturun, hemen hemen her şey HTTP konuşabilir, böylece size birçok dil kazandırır.

  2. Bir dil çalışma zamanına bağlanabilecek bir şey oluşturun; bu, onu birçok farklı dile bağlamak için bir yol bulmanız gerekeceğinden oldukça zaman alıcı olacaktır.


Aklında ne tür bir HTTP arayüzü var?
Anderson Green,

@AndersonGreen Önemli değil (bir ağ soketini açabilen herhangi bir dil HTTP konuşabildiği için), ancak REST kullanışlı bir sözde standarttır.
Monica'yı

7
REST + JSON makul bir çözüm olacaktır
David Hayes

Ayrıca, iletişim kurmak için HTTP kullanmanın hemen hemen her dilin uygulamanızın işlevleriyle etkileşime girmesini sağladığını kabul ediyorum.
Sadece Bolivyalı Burada

30

C veya C ++ 'ın amacınıza en uygun olacağını düşünüyorum. C veya C ++ API'nizden dil ciltleri oluşturmak için SWIG (Basitleştirilmiş Sarıcı ve Arayüz Jeneratörü) kullanabilirsiniz.

SWIG, C ve C ++ ile yazılmış programları çeşitli üst düzey programlama dilleriyle birleştiren bir yazılım geliştirme aracıdır. SWIG, Perl, PHP, Python, Tcl ve Ruby gibi genel betik dilleri dahil olmak üzere farklı türlerdeki hedef dillerle kullanılır. Desteklenen dillerin listesiayrıca C #, Common Lisp (CLISP, Allegro CL, CFFI, UFFI), D, Go dili, Android, Java dahil Java, Lua, Modula-3, OCAML, Octave ve R gibi komut dosyası olmayan dilleri de içerir. uygulamalar (Guile, MzScheme / Racket, Chicken) desteklenmektedir. SWIG, en yaygın olarak yorumlanmış veya derlenmiş programlama ortamları, kullanıcı arayüzleri ve C / C ++ yazılımının test edilmesi ve prototiplenmesi için bir araç olarak kullanılır. SWIG, tipik olarak C / C ++ arayüzlerini ayrıştırmak ve yukarıdaki hedef dillerin C / C ++ kodunu çağırması için gereken 'yapıştırıcı kodunu' oluşturmak için kullanılır. SWIG ayrıca ayrıştırma ağacını XML ve Lisp ifadeleri şeklinde de dışa aktarabilir. SWIG özgür bir yazılımdır ve SWIG'in ürettiği kod hem ticari hem de ticari olmayan projelerle uyumludur ...


32
C ++ korkunç bir seçim olacaktır. Bununla ilgili çok sayıda sorun var: bir çalışma zamanı kitaplığına bağımlılık, belirtilmemiş ABI (özellikle karışıklık), vb. SWIG oldukça sınırlı bir şey. Python Qt ciltlemelerinin etrafındaki karmaşık tüm altyapıyı görün.
SK-mantık

14
@ SK-mantık: Pek değil. C sadece C ++ gibi bir çalışma zamanı lib ihtiyacı var. ABI, C ++ ile extern "C"dıştan C-uyumlu olarak kontrol edilebilir . Bu nedenle, C ++ 'ın (yüksek tip güvenliği, kütüphanelerin) iç avantajlarına sahip olursunuz, ancak C'nin dış avantajları (fiili ABI standardı)
MSalters

3
@ SK-mantık Belirtilmemiş ABI sadece çözülmüş bir sorundur, bkz. SWIG, Boost.Python ve diğer dil bağlarının bir ana bilgisayarı.
Konrad Rudolph

3
@MSalters istisnalar ve kütüphane sınırları ötesinde onların genel olmayan workiness hakkında unutmayın
sehe

3
C ++ önerisi için -1. C kolaydır, C ++ işleri gereksiz yere zorlaştırır.
Ernest Friedman-Hill

23

Neredeyse 2 yol var:

  • bir C API. Neredeyse hiç bir dil vardı ve bir C kütüphanesi yükleyecekti. Bunu nasıl yaptığınız kaynak dile bağlıdır.
  • bir çeşit RPC mekanizması. Bu HTTP üzerinden çalışan bir REST API'si veya bir soket üzerinden çalışan ikili bir arayüz olabilir. En düşük ortak payda mekanizmasına (örneğin bir soket) gitmediğiniz sürece, müşteri erişim rutinlerine sahip olmama riskiniz vardır (örneğin, bazı dillerde SOAP kullanılarak uygulanan bir API'yi çağırmak için doğru SOAP istemcilerine sahip olma hakkı yoktur veya birlikte çalışabilirlik sorunları vardır). En basitine, bir HTTP / REST arayüzü veya bir sokete bağlı kalın. Yuvalar, arabirimi istemcilere göstermek için bir HTTP sunucusuna ihtiyaç duymamaları ve istemci ile aynı sunucu üzerinde daha iyi performansla daha kolay çalışabilmeleri avantajına sahiptir.

Bunun için gereken iş, kullanılan sisteme bağlı olarak değişir, örneğin bir soket arayüzü işe yarar, ancak istemci tarafı kitaplıkları, http kitaplıklarına göre daha düşük düzeyde olma eğilimindedir.

Kullanmak istediğiniz tüm dilleri destekleyen bir ağ kütüphanesi bulmayı deneyebilir ve API'yi bu kitaplık açısından uygulayabilirsiniz - örneğin, ZeroMQ kullanmak size çok fazla esneklik verir, böylece API'nizi ZeroMQ arabirimlerini kullanarak yazabilirsiniz ve o zaman API’nizi aramak isteyen herhangi bir dilin ZeroMQ istemci kitaplığını kullanması gerekir. Çok çeşitli dilleri destekleyen bir kitaplık seçin ve en iyi performans için işlem içi ve iletişim dışı iletişimi sağlar.


Peki API'yi birden çok dilde yazmak istesem hangi adımları atmam gerekir? (Benim durumumda, bu diller Javascript, C ++ ve Java olacaktır.)
Anderson Green,

Dillerin her biri için sadece 3 ayrı RESTful API yazmalı mıyım?
Anderson Green,

Bu dillerin her birine, yükleme ve altta yatan C dll'yi çağıran yerel bir sarmalayıcı yazarsınız. Ya da C ++ 'a yazın ve SWIG kullanarak bunu sizin için yapın. Bir REST API kullanıyorsanız, aynı durum geçerlidir, ya tek bir API ve ardından 3 sarmalayıcı yazın, ancak bir REST API yazıyorsanız, her dil doğrudan REST API'sini çağırabilir - rahatsız etmeyin bir sarıcı ile.
gbjbaanb

Dll (dinamik olarak bağlanmış kütüphane), Windows dışında herhangi bir platformla uyumlu olur mu? Burada platformlar arası uyumluluğa ihtiyacım var.
Anderson Green,

hayır, onu diğer platformlar için derlemeniz gerekecek. Örneğin Linux, .dll yerine .so kullanır. Sadece düz bir yeniden derleme gereklidir, hiçbir kod değişikliği yoktur (veya çok küçük).
gbjbaanb

12

Performans ve çağrı gecikmesi bir sorun değilse, kapsamlı bir komut satırı arayüzü sağlamayı düşünün (muhtemelen üzerine bir komut dosyası dili kullanarak). ImageMagick böyle bir "API" ye iyi bir örnek olabilir. Bir başka güzel örnek ise Tk toolkit.


Komut satırı yabancı fonksiyon arayüzü oluşturmak amacıyla hangi komut dosyası dilini ve / veya programlama dilini önerirsiniz? Ayrıca, bu tür arayüzlerin somut örneklerini buldunuz mu?
Anderson Green,

@AndersonGreen, iyi metaprogramming ile herhangi bir dil böyle bir amaç için tamam. Örneğin, Scheme, MetaLua, diğer gömülebilir diğer Lisps, Tcl. Kendi komut dilinizi de kolayca uygulayabilirsiniz. Birçok CAD / CAE sistemi bu şekilde çalışır. Daha önce bahsedilen bir Tk başka bir tipik örnek.
SK-mantık

Bir komut satırı arayüzünü bu şekilde kullanmak için, belirli bir komut için ( whoamikullanıcı adını almak için Ubuntu'da olduğu gibi) konsol çıktısını alır mıydınız, yoksa aklınızda başka bir şey mi var?
Anderson Green,

@AndersonGreen, boru stdin ve stdout çoğu durumda yeterli olacaktır.
SK-mantık

5

API ile tam olarak ne demek istiyorsun?

Pek çok platformda, bir DLL veya benzer bir yapıya bağlanabilir, ancak belirli bir yerel hedef (Intel / ARM) veya endianness hala geçerli olmak için yeniden derlenmeniz gerekir mi? Belirli bir ikili arayüz, veri türü sorunları veya yapıları nedeniyle (bazı dilleri iyi desteklemeyen dillere döndürülmeye çalışan işaretçiler) nedeniyle belirli dillerle ilgili hala zorluklar yaşayabilir; bu nedenle, API'nin tasarımını dikkate almamalısınız. bazı dilleri dışlamak veya bu dillerden faydalanmak için hantal.

C gibi taşınabilir bir şey ve bir DLL'deki ikili uç noktalara dayanan bir arabirim iyi olabilir ve genellikle çoğu platformda ve çoğu dilde çağrılabilir, ancak farklı şekilde derlenmesi ve / veya farklı lezzetlerde sunulması veya farklı statik kitaplıklara bağlanması gerekebilir.

Bana öyle geliyor ki, kütüphane ya da hizmetinizi yazdığınız dil seçiminiz ya da tanımı ne olursa olsun, API'nin sunduğu platform / hizmet hakkında daha fazla bilgi verinceye kadar sorunun özü yoktur. Bir ağ yığınının kullanılabilir olduğunu ve doğrudan bağlı işlev çağrısı düzeyinde performansın bir gereklilik olmadığını varsayabilir, API, istekleri şeffaf hale getirmek için istemci dilinin bir tür silme ile kolayca HTTP tabanlı olabilir.

Genel olarak, bu sorunun gerçek dünyada faydalı olması için aşırı geniş olduğunu düşünüyorum, çünkü sunulan hizmet türü için ne tür bir API'nin uygun olabileceğine dair bir gösterge vermediniz.


2

Bir RPC mekanizması kullanılmasını öneren yukarıdaki cevaplara eklemek için. Apache Thrift'i kullanabilirsiniz. ( Http://thrift.apache.org/ ). Temel olarak bir RPC çerçevesidir.

Thrift wiki'ye göre:

Apache Thrift yazılım çerçevesi, ölçeklenebilir çapraz dil hizmetlerinin geliştirilmesi için, bir yazılım yığınını C ++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C #, arasında verimli ve sorunsuz çalışan hizmetler oluşturmak için bir kod oluşturma motoruyla birleştirir Kakao, JavaScript, Node.js, Smalltalk, OCaml ve Delphi ve diğer diller


Yabancı fonksiyon çağrıları Apache Thrift kullanılarak nasıl yapılabilir?
Anderson Green,

0

Herhangi bir dilin geçmesi gereken paraşütlerle çağırmak için işlevli bir metin dosyası yazmasını sağlayın. Bir dizini izlerken "herkesle anlaşıyorum" uygulamanızı ve bir process-call.txt dosyasını gördükten sonra çalışmasını sağlayın. Sunucu veya ağ protokolü yok; bilgisayar dili olmayan bir yöntem bile işlevleri başlatabilir. Bir kişi bile sadece metin dosyasını oluşturabilir.

İçerik şöyle olabilir:

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

;) bir cevap almak için sonsuza kadar bekleyebilirsin. Sadece birkaç bayt diğer sürece zorlaman gerekiyor, ama eminim bu tüm özellik değil.


Sadece bir komut satırı arayüzü + stdin / stdout olabilir zaman aşırı karmaşık görünüyor.
Monica'yı

1
Daha iyi bir çağrı ++ + 1 olabilir, Brendan. Asla eylemde görmedim ama bir zamanlar insanlar baytları aktarmak için kartta delikler açıyorlardı.
Pareshkumar

4
Bu bir şaka cevabı değil mi? Bunu burada yapmayız.
Ernest Friedman-Hill

Pekala, fdisk ve / root kısmı bir şaka, ama ben 5 milyondan fazla bir platform ar-ge (geliştirici ve analist) olarak görev yaptım. Bu REST yöntemini kullanarak, müşteri için milyonlarca sevk edilebilir fiziksel (pdf ve e-posta değil) öğeyi tüketin (öğe başına yüzlerce MB arasında değişen Dosyaların işlenmesiyle). Büyük sistem üçlülüğü-SAP-MS Office-PLC Drivewrs-PDF İş Akışı'nı bir araya getirdik ve düz eski UTF-8 metin dosyaları ve zip içeren bir zip ile birlikte iyi çalışan, ve hiçbir HTTP bs yükü yok.
Pareshkumar

Bir soru sorabilir miyim? Neden hiç kimse JSON'un bir şaka olduğunu düşünmüyor? Tavsiye ettiğim şey nasıl farklı? Json'u kullanırdık / kullanabilirdik ama 2003'te yoktu. XML çok şişmandı, ama o zamanlar bu, en pratik ve en basit ruh değil, ayın tadıydı.
Pareshkumar

0

OpenGL, tanımladığınız şeye iyi bir örnektir - C dilinde yazılmış, diğer dillerde kolayca ciltlenebilecek şekilde tasarlanmış bir API'dir.

  1. C kütüphaneleri çoğu programlama dilinden çağrılabilir (genellikle derlenmiş uzantılar veya PyPy'nin ctypeskütüphanesi vb. Gibi)

  2. Tüm işlevler basit veri türlerini argüman olarak alır (boolean, tamsayı, kayan nokta, sabitler, diziler), işaretçileri alan işlevler bazı dillere çevrilmesi zor olabilir.

  3. Kendi sayısal veri türlerine sahip olmak, hassasiyetini ve imzasını belirtir (oysa int floatfarklı olabilir)

Sonuçta ortaya çıkan API, yalnızca C kullanıcılarını hedef alıyorsa, yazabileceğiniz en iyi C API değil. Bununla birlikte, işlevlerin neredeyse doğrudan başka bir dile maruz kalabileceği anlamına gelir (örn. PyOpenGL belgeleri, çoğu oldukça az olan farklılıkları listeler)

Bu ayrıntılı API'nin üzerine, etrafına daha fazla "geliştirici dostu" sarmalayıcı yazabilirsiniz (oyun çerçeveleri ve benzeri)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.