Як я можу написати набір функцій, які можна викликати з (майже) будь-якої мови програмування?


33

Я хотів би знайти спосіб написання API, до якого можна отримати доступ з будь-якої іншої мови програмування за допомогою прив'язки мови (або якоїсь іншої рамки). Чи можна це зробити? Якщо так, то яка програма програмування була б найбільш підходящою для написання API "міжмовної мови"? Моя мета - створити єдиний набір функцій, до яких я можу отримати доступ з будь-якої мови програмування, з якою я працюю, так що мені не потрібно буде вручну переписувати весь API на кожній мові.


4
Якщо ви просто хочете мати можливість сказати "ми підтримуємо ВСЕ" з маркетингових причин, ви можете просто написати DLL низького рівня або спільну бібліотеку в C. Якщо ви хочете, щоб хто-небудь сказав, Java, використовував свою річ, ви б краще забезпечити інтерфейс Java.
mjfgates

1
Ви говорите "(майже) будь-який", які мови ви б виключили для цього? Або які для вас найважливіші?
funkybro

22
Веб-сервіс? Ви можете записати деякі функції, наприклад, в php. Практично будь-яка мова має можливість взаємодіяти із веб-сторінками, надавати аргументи та читати результати.
Пітер Б

7
+1, тому що це цікаве питання - але ваше питання було б покращено, сказавши, чому ви хочете це зробити. Які ваші цілі?
TarkaDaal

@PieterB => відповідь.
Конрад Рудольф

Відповіді:


44

У вас є кілька варіантів:

  1. Створіть інтерфейс HTTP, майже все може говорити HTTP, щоб отримати багато мов.

  2. Створіть щось, що може бути пов’язано з мовою виконання, це забирає багато часу, оскільки вам знадобиться знайти спосіб підключення його до багатьох різних мов.


Який інтерфейс HTTP ви конкретно маєте на увазі?
Андерсон Грін

@AndersonGreen Це не має значення (оскільки будь-яка мова, яка може відкрити мережевий сокет, може говорити HTTP), але REST - корисний псевдостандарт.
Відновіть Моніку

7
REST + JSON було б розумним рішенням
Девід Хейс

Я також погоджуюся, що використання HTTP для спілкування дозволяє майже кожній мові там взаємодіяти з функціями вашого додатка.
Тільки болівійський тут,

30

Я думаю, що C або C ++ було б найбільш підходящим для вашої мети. Ви можете використовувати SWIG (спрощений генератор і інтерфейс) для створення мовних зв'язків з вашого C або C ++ API.

SWIG - це інструмент розробки програмного забезпечення, який з'єднує програми, написані на C і C ++, з різними мовами програмування високого рівня. SWIG використовується з різними типами цільових мов, включаючи поширені мови скриптів, такі як Perl, PHP, Python, Tcl та Ruby. Список підтримуваних мовтакож включає не-сценарії, такі як C #, Common Lisp (CLISP, Allegro CL, CFFI, UFFI), D, Go, Java, включаючи Android, Lua, Modula-3, OCAML, Octave та R. Також кілька інтерпретованих та складених схем реалізації (Guile, MzScheme / Racket, Chicken) підтримуються. SWIG найчастіше використовується для створення інтерпретованих або складених середовищ програмування на високому рівні, інтерфейсів користувача та як інструмент для тестування та прототипування програмного забезпечення C / C ++. SWIG, як правило, використовується для розбору інтерфейсів C / C ++ та генерування «коду клею», необхідного для вищезазначених мов для виклику в код C / C ++. SWIG також може експортувати своє дерево розбору у вигляді XML та s-виразів Lisp. SWIG - це вільне програмне забезпечення, і код, який створює SWIG, сумісний як з комерційними, так і з некомерційними проектами ...


32
C ++ був би жахливим вибором. З цим виникають численні проблеми: залежність від бібліотеки часу виконання, не визначений ABI (особливо манінг) тощо. Створення зв'язків із заголовків C ++ надзвичайно складно. SWIG - досить обмежена річ. Перегляньте всю складну інфраструктуру навколо, скажімо, зв'язків Python Qt.
SK-логіка

14
@ SK-логіка: Не дуже. C потрібна вікно часу виконання, як і C ++. ABI можна керувати в C ++ через extern "C"так, щоб він був сумісним із зовнішньої сторони. Отже, у вас є внутрішні переваги C ++ (вища безпека типу, бібліотеки), але зовнішні переваги C (фактично стандарт ABI)
MSalters

3
@ SK-логіка Невказане ABI - це просто вирішена проблема, див. SWIG, Boost.Python та безліч інших мовних прив’язок.
Конрад Рудольф

3
@MSalters не забувати про винятки і їх не загального workiness через бібліотеки кордонів
sehe

3
-1 для пропозиції C ++. C легко, C ++ робить речі непотрібними важкими.
Ернест Фрідман-Хілл

23

Є майже два способи:

  • API C. Практично будь-коли мова, яка там коли-небудь була, буде завантажувати бібліотеку С і викликати її функції. Як це зробити, залежить від мови джерела.
  • якийсь механізм RPC. Це може бути API REST, що працює над HTTP, або бінарний інтерфейс, що працює над сокетом. Якщо ви не використовуєте найменший механізм загального знаменника (наприклад, сокет), ви ризикуєте не мати підпрограми доступу клієнта (наприклад, деякі мови не мають права клієнти SOAP викликати API, реалізований за допомогою SOAP, або є проблеми інтероперабельності). Дотримуйтесь найпростішого - або HTTP / REST-інтерфейсу, або сокета. Сокети мають перевагу в тому, що їм не потрібен сервер HTTP для відкриття інтерфейсу для клієнтів, і вони можуть легше працювати на тому ж сервері, що і клієнт, з кращою продуктивністю.

Робота, необхідна для цих змін, залежить від використовуваної системи, наприклад, буде працювати інтерфейс сокета, але бібліотеки на стороні клієнта мають тенденцію бути більш низьким рівнем порівняно з http-бібліотеками.

Ви можете спробувати знайти мережеву бібліотеку, яка підтримує всі мови, якими ви хочете користуватися, та реалізувати API з точки зору цієї бібліотеки - наприклад, використання ZeroMQ дає вам велику гнучкість, тому ви б писали свій API за допомогою інтерфейсів ZeroMQ та то будь-яка мова, яка хоче зателефонувати у ваш API, повинна використовувати для цього клієнтську бібліотеку ZeroMQ. Виберіть бібліотеку, яка підтримує широкий діапазон мов, а також дозволяє здійснювати як обробку, так і позасистемне спілкування для найкращої продуктивності.


Отже, які кроки мені потрібно було б зробити, якщо я хотів би також написати API на кількох мовах? (У моєму випадку цими мовами будуть Javascript, C ++ та Java.)
Anderson Green

Чи варто просто написати 3 окремі API RESTful для кожної з мов?
Андерсон Грін

Ви пишете нативну обгортку на кожній з цих мов, яка обробляє завантаження та виклик базового C dll. Або напишіть це на C ++ і використовуйте SWIG, щоб зробити це за вас. Якщо ви використовуєте API REST, то застосовується те саме, або написати один API, а потім 3 обгортки, але якщо ви пишете API REST, то кожна мова зможе викликати API REST безпосередньо - не турбуйте з обгорткою.
gbjbaanb

Чи буде dll (динамічно пов'язана бібліотека) сумісною будь-якій платформі, крім Windows? Мені тут потрібна міжплатформна сумісність.
Андерсон Грін,

ні, вам потрібно буде перекомпілювати його для інших платформ. Наприклад, Linux використовує .so замість .dll. Потрібна просто пряма перекомпіляція, ніяких (або дуже незначних) змін коду.
gbjbaanb

12

Якщо продуктивність та затримка викликів не є проблемою, подумайте про надання всебічного інтерфейсу командного рядка (можливо, використовуючи мову сценаріїв поверх нього). ImageMagick може бути хорошим прикладом такого "API". Ще один хороший приклад - інструментарій Tk.


Яку мову сценаріїв та / або мову програмування ви б рекомендували для створення інтерфейсу зовнішньої функції командного рядка? Також ви знайшли конкретні приклади таких інтерфейсів?
Андерсон Грін

@AndersonGreen, будь-яка мова з гідною метапрограмуванням нормальна для такої мети. Наприклад, схема, MetaLua, різні інші вбудовувані Lisps, Tcl. Ви також можете легко реалізувати свою власну мову команд. Багато систем CAD / CAE працюють таким чином. Вже згаданий Tk - ще один типовий приклад.
SK-логіка

Щоб таким чином використовувати інтерфейс командного рядка, ви отримаєте консольний вихід для певної команди (наприклад, whoamiна Ubuntu, щоб отримати ім’я користувача), або ви мали на увазі щось інше?
Андерсон Грін

@AndersonGreen, трубопроводи stdin і stdout повинні бути достатніми в більшості випадків.
SK-логіка

5

Під API, що саме ви маєте на увазі?

На багатьох платформах ви могли б зв’язатися з DLL або подібною конструкцією, але вам доведеться перекомпілювати для конкретної націленої цілі (Intel / ARM) або все-таки кваліфікованість? У певному бінарному інтерфейсі все ще можуть виникнути труднощі з певними мовами через проблеми або конструкції типу даних (вказівники, які намагаються повернутись до мов, які не підтримують їх добре), тому вам також доведеться врахувати дизайн самого API, щоб не щоб виключити деякі мови або зробити їх використання з цих мов громіздкими.

Щось таке портативне, як C та інтерфейс, заснований на бінарних кінцевих точках у DLL, може бути відмінним та загальним для дзвінка на більшості платформ та з більшості мов, але, можливо, його потрібно скласти по-різному та / або запропонувати в різних смаках або пов'язати з різними статичними бібліотеками.

Мені здається, що вибір мови, якою ви пишете свою бібліотеку чи службу, або що б там не було, за визначенням не суттєвий для цього питання, поки ви не дасте більше інформації про платформу / службу, яку API викриває. Якщо ви можете припустити, що мережевий стек доступний, а продуктивність на рівні прямого зв’язку функціонування на рівні виклику не є вимогою, API може бути легко заснований на HTTP з якоюсь хиткою для мови клієнта, щоб зробити запити прозорими.

Я думаю, що в цілому це питання є надто широким, щоб бути корисним у реальному світі, оскільки ви не дали вказівки щодо того, який тип API може бути придатним з огляду на тип послуги, що пропонується.


2

Додайте до вище відповідей, які пропонують використовувати механізм RPC. Ви можете використовувати Apache Thrift. ( Http://thrift.apache.org/ ). В основному це рамка RPC.

Відповідно до Вікі-ощадливості:

Програмне забезпечення Apache Thrift для розробки масштабних мовних послуг поєднує стек програмного забезпечення з механізмом генерації коду для створення служб, які ефективно і безперебійно працюють між C ++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C #, Какао, JavaScript, Node.js, Smalltalk, OCaml і Delphi та інші мови


Як можна робити дзвінки з іноземних функцій за допомогою Apache Thrift?
Андерсон Грін

0

Нехай будь-яка мова випише текстовий файл із функцією для дзвінка з парами для передачі. Попросіть додаток "Я погоджуюся з ким-небудь", щоб переглядати каталог, і як тільки він побачить процес-call.txt, перейдіть на роботу. Відсутність серверів або мережевих протоколів; навіть некомп'ютерний мовний метод може запускати функції. Навіть людина могла просто створити текстовий файл.

Вміст може виглядати так:

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

;) Ви можете зачекати вічно, щоб отримати відповідь. Вам просто потрібно просунути кілька байт до іншого процесу, але я впевнений, що це не вся специфікація.


Здається, занадто складним, коли ви могли просто мати інтерфейс командного рядка + stdin / stdout.
Відновіть Моніку

1
Ще краще зателефонувати може ++ 1, Брендан. Я ніколи не бачив його в дії, але колись люди пробивали дірки в картці, щоб переносити байти навколо.
Pareshkumar

4
Це жартівлива відповідь, правда? Ми цього не робимо.
Ернест Фрідман-Хілл

Ну, fdisk та / root частина - це жарт, але я був залучений як розробник платформи і розробник (розробник та аналітик) протягом більше 5 років, щоб створити продукт платформи, який дав блага в 10-х мільйонах доларів. Він виплюває мільйони фізичних (не PDF та електронних листів) елементів для клієнта (з обробкою файлів у сотнях МБ на предмет) за допомогою цього типу методу REST. У нас була основна системна триолгія-SAP-MS Office-PLC Drivewrs-PDF Workflow, яка зводила один до одного і добре працювала разом із звичайними старими текстовими файлами UTF-8 та блискавкою, що міститься в zip-in-zip, і відсутність накладних даних HTTP.
Парешкумар

Чи можу я задати питання? Чому ніхто не думає, що JSON - це жарт? Як те, що я рекомендував інакше? Ми могли б / могли використати json, але цього не було в 2003 році. XML занадто жирний, але тоді це був аромат місяця не самий спокійний і найпростіший настрій.
Парешкумар

0

OpenGL - хороший приклад того, що ви описуєте - це API, написаний на C, розроблений таким чином, що легко писати прив’язки іншими мовами

  1. Бібліотеки C можна викликати з більшості мов програмування (як правило, як складені розширення або такі речі, як ctypesбібліотека PyPy тощо)

  2. Усі функції приймають прості типи даних як аргументи (булева, ціла, плаваюча точка, константи, масиви), оскільки функції, що приймають покажчики, можуть бути незручними для перекладу на деякі мови

  3. Маючи власні числові типи даних, які визначають точність та підписаність (тоді як int floatтощо можуть відрізнятися)

Отриманий API не обов'язково є найкращим у використанні API API, який ви могли написати, якщо націлювати лише на користувачів C. Однак це означає, що функції можуть бути майже безпосередньо піддані впливу іншої мови (наприклад, документи PyOpenGL перераховують відмінності, більшість з яких досить мінімальні)

Зверху на цей багатослівний API, ви можете написати ще "обгортки для розробників" навколо цього (ігрові рамки тощо)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.