Как я могу написать набор функций, которые могут быть вызваны из (почти) любого языка программирования?

33

Я хотел бы найти способ написать API, к которому можно получить доступ из любого другого языка программирования через привязки языка (или некоторую другую структуру). Можно ли это сделать? Если да, то какой язык программирования будет наиболее подходящим для написания «междисциплинарного» API? Моя цель - создать единый набор функций, к которым я могу получить доступ из любого языка программирования, с которым я работаю, чтобы мне не пришлось вручную переписывать весь API на каждом языке.

Андерсон Грин
источник
4
Если вы просто хотите сказать «мы поддерживаем ВСЕ» по маркетинговым причинам, вы можете просто написать низкоуровневую DLL или общую библиотеку на C. Если вы хотите, чтобы кто-нибудь, скажем, Java, использовал вашу штуковину, вы бы лучше предоставить интерфейс Java.
mjfgates
1
Вы говорите «(почти) любой», какие языки вы бы исключили для этой цели? Или какие из них наиболее важны для вас?
фанкибро
22
Веб-сервис? Вы можете написать некоторые функции, например, в php. Практически любой язык имеет возможность взаимодействовать с веб-страницами, предоставлять аргументы и читать результаты.
Питер Б
7
+1, потому что это интересный вопрос - но ваш вопрос будет улучшен, если вы скажете, почему вы хотите это сделать. Каковы твои цели?
TarkaDaal
@PieterB => ответ.
Конрад Рудольф

Ответы:

44

У вас есть несколько вариантов:

  1. Создайте интерфейс HTTP, почти все могут общаться по протоколу HTTP, так что вы получите много языков.

  2. Создайте что-то, что может быть связано с языковой средой выполнения, это будет довольно трудоемким, так как вам нужно будет найти способ подключить это к множеству разных языков.

Захари К
источник
Какой именно HTTP-интерфейс вы имеете в виду?
Андерсон Грин
@AndersonGreen Это не должно иметь значения (поскольку любой язык, который может открыть сетевой сокет, может говорить по HTTP), но REST является полезным псевдостандартом.
Восстановить Монику
7
REST + JSON будет разумным решением
Дэвид Хейс,
Я также согласен, что использование 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, 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, совместим как с коммерческими, так и с некоммерческими проектами ...

LMC
источник
32
C ++ был бы ужасным выбором. С этим связано множество проблем: зависимость от библиотеки времени выполнения, неопределенный ABI (особенно искажение) и т. Д. Генерирование привязок из заголовков C ++ чрезвычайно сложно. SWIG - довольно ограниченная вещь. Просмотрите всю слишком сложную инфраструктуру, скажем, с привязками Python Qt.
SK-logic
14
@ SK-логика: не совсем. C нужна библиотека времени выполнения, как и C ++. ABI может управляться в C ++ через, extern "C"так что он является C-совместимым снаружи. Следовательно, у вас есть внутренние преимущества C ++ (более высокая безопасность типов, библиотеки), но внешние преимущества C (стандарт де-факто ABI)
MSalters
3
@ SK-logic Неопределенный ABI - это просто решаемая проблема, см. SWIG, Boost.Python и множество других языковых привязок.
Конрад Рудольф
3
@MSalters не забывайте об исключениях и их общей неработоспособности за пределами библиотеки
сехе
3
-1 для предложения C ++. C легко, C ++ делает вещи бесполезно сложными.
Эрнест Фридман-Хилл
23

Есть в значительной степени 2 способа:

  • C API. Практически когда-либо существующий язык загружает библиотеку C и вызывает ее функции. Как вы это сделаете, зависит от исходного языка.
  • какой-то механизм RPC. Это может быть REST API, работающий через HTTP, или двоичный интерфейс, работающий через сокет. Если вы не используете механизм с наименьшим общим знаменателем (например, сокет), вы рискуете не иметь процедур клиентского доступа (например, некоторые языки не имеют правильных клиентов SOAP для вызова API, реализованного с использованием SOAP, или возникают проблемы взаимодействия). Придерживайтесь самого простого: либо интерфейса HTTP / REST, либо сокета. Преимущество сокетов заключается в том, что им не требуется HTTP-сервер для предоставления интерфейса клиентам, и они могут легче работать на том же сервере, что и клиент, с более высокой производительностью.

Работа, необходимая для этого, изменяется в зависимости от используемой системы, например, интерфейс сокетов будет работать, но библиотеки на стороне клиента имеют тенденцию быть более низкоуровневыми по сравнению с библиотеками http.

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

gbjbaanb
источник
Итак, какие шаги мне нужно предпринять, если я хочу написать API на нескольких языках? (В моем случае, такими языками были бы Javascript, C ++ и Java.)
Андерсон Грин
Должен ли я написать 3 отдельных API RESTful для каждого из языков?
Андерсон Грин
Вы пишете собственную обертку на каждом из этих языков, которая обрабатывает загрузку и вызов базового Cll. Или напишите это на C ++ и используйте SWIG, чтобы сделать это для вас. Если вы используете REST API, то применяется то же самое, либо пишите один API, а затем 3 оболочки, но если вы пишете REST API, то каждый язык сможет напрямую вызывать REST API - не беспокойтесь с оберткой.
gbjbaanb
Будет ли dll (динамически связанная библиотека) совместима с какой-либо платформой, кроме Windows? Мне нужна кроссплатформенная совместимость здесь.
Андерсон Грин
нет, вам нужно перекомпилировать его для других платформ. Linux, например, использует .so вместо .dll. Нужна просто прямая перекомпиляция, без (или очень незначительных) изменений кода.
gbjbaanb
12

Если производительность и задержка вызова не являются проблемой, рассмотрите возможность предоставления всестороннего интерфейса командной строки (возможно, с использованием языка сценариев поверх него). ImageMagick может быть хорошим примером такого «API». Другим хорошим примером является инструментарий Tk.

SK-логика
источник
Какой язык сценариев и / или язык программирования вы бы порекомендовали для создания интерфейса сторонней функции командной строки? Кроме того, вы нашли какие-либо конкретные примеры таких интерфейсов?
Андерсон Грин
@AndersonGreen, любой язык с достойным метапрограммированием подходит для такой цели. Например, Scheme, MetaLua, различные другие встраиваемые Lisps, Tcl. Вы также можете легко реализовать свой собственный командный язык. Многие системы CAD / CAE работают таким образом. Уже упомянутый Tk является еще одним типичным примером.
SK-logic
Чтобы использовать интерфейс командной строки таким образом, вы бы получили консольный вывод для определенной команды (например, в whoamiUbuntu для получения имени пользователя), или вы имели в виду что-то еще?
Андерсон Грин
@AndersonGreen, в большинстве случаев должно быть достаточно стандартных stdin и stdout.
SK-logic
5

Под API, что именно вы имеете в виду?

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

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

Мне кажется, что выбор языка, на котором вы пишете свою библиотеку или службу или что-то еще, по определению не является неотъемлемой частью вопроса, пока вы не дадите больше о платформе / услуге, которую предоставляет API. Если вы можете предположить, что сетевой стек доступен, а производительность на уровне вызовов функций с прямой связью не является обязательным требованием, API может легко основываться на HTTP с некоторой оболочкой для языка клиента, чтобы сделать запросы прозрачными.

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

Кейд Ру
источник
2

Чтобы добавить выше ответы, которые предлагают использовать механизм RPC. Вы можете использовать Apache Thrift. ( Http://thrift.apache.org/ ). Это в основном фреймворк RPC.

Согласно Thrift Wiki:

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

gt5050
источник
Как можно выполнять вызовы внешних функций с помощью Apache Thrift?
Андерсон Грин
0

Пусть любой язык напишет текстовый файл с функцией для вызова с передаваемыми параметрами. Пусть ваше приложение «Я с кем-нибудь общаюсь» наблюдает за каталогом, и как только оно видит process-call.txt, пусть оно работает. Нет серверов или сетевых протоколов; даже метод некомпьютерного языка может инициировать функции. Даже человек может просто создать текстовый файл.

Контент может выглядеть так:

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

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

Pareshkumar
источник
Кажется слишком сложным, когда вы можете просто иметь интерфейс командной строки + stdin / stdout.
Восстановить Монику
1
Еще лучше позвонить на ++ 1, Брендан. Я никогда не видел это в действии, но когда-то люди пробивали отверстия в карточке для передачи байтов.
Парешкумар
4
Это шутливый ответ, верно? Мы не делаем это здесь.
Эрнест Фридман-Хилл
Что ж, часть fdisk и / root - это шутка, но я более 5 лет участвовал как исследователь и разработчик платформы (разработчик и аналитик), создавая продукт-платформу, который приносил прибыль в десятки миллионов долларов. Он выдает миллионы отправляемых физических (не PDF-файлов и электронных писем) элементов для клиента (с обработкой файлов размером в сотни МБ на элемент) с использованием этого типа метода REST. У нас была основная система triolgy-SAP-MS Office-PLC Drivewrs-PDF Workflow, все они слились друг с другом и хорошо работали вместе с простыми старыми текстовыми файлами UTF-8 и почтовым индексом с почтовым индексом и почтовым индексом, и нет HTTP bs накладных расходов.
Парешкумар
Могу я задать вопрос? Почему никто не думает, что JSON - это шутка? Чем то, что я рекомендовал, отличается? Мы могли бы / могли бы использовать json, но его не было в 2003 году. XML слишком толстый, но тогда это был аромат месяца, а не самой практичной и самой простой идеи.
Парешкумар
0

OpenGL - хороший пример того, что вы описываете - это API, написанный на C, разработанный таким образом, чтобы легко писать привязки на других языках.

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

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

  3. Наличие собственных числовых типов данных, которые определяют точность и подпись (тогда как и int floatт. Д. Могут отличаться)

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

Помимо этого подробного API, вы можете написать больше «дружественных для разработчиков» оберток вокруг этого (игровые платформы и тому подобное)

DBR
источник