Como posso escrever um conjunto de funções que podem ser chamadas de (quase) qualquer linguagem de programação?


33

Gostaria de encontrar uma maneira de escrever uma API que possa ser acessada de qualquer outra linguagem de programação por meio de ligações de linguagem (ou alguma outra estrutura). É possível fazer isso? Em caso afirmativo, qual linguagem de programação seria a mais adequada para escrever uma API "entre idiomas"? Meu objetivo é criar um único conjunto de funções que eu possa acessar a partir de qualquer linguagem de programação com a qual estou trabalhando, para não precisar reescrever manualmente a API inteira em cada idioma.


4
Se você quiser apenas dizer "nós apoiamos TUDO" por razões de marketing, basta escrever uma DLL de baixo nível ou uma biblioteca compartilhada em C. Se você quiser que alguém diga, Java, para usar suas coisas, forneça melhor uma interface Java.
Mjfgates

1
Você diz "(quase) algum", quais idiomas você excluiria para esse fim? Ou quais são as mais importantes para você?
Funkybro

22
Serviço de internet? Você pode escrever algumas funções, por exemplo, php. Quase qualquer idioma tem a possibilidade de interagir com páginas da web, fornecer argumentos e ler os resultados.
Pieter B

7
+1 porque é uma pergunta interessante - mas sua pergunta seria melhorada ao dizer por que você deseja fazer isso. Quais são seus objetivos?
TarkaDaal

@PieterB => answer.
22912 Konrad Rudolph

Respostas:


44

Você tem poucas opções:

  1. Crie uma interface HTTP, quase tudo pode falar HTTP, para que você obtenha muitas linguagens.

  2. Crie algo que possa ser vinculado a um tempo de execução do idioma. Isso consumirá bastante tempo, pois você precisará encontrar uma maneira de conectá-lo a vários idiomas diferentes.


Que tipo de interface HTTP você tem em mente, especificamente?
Anderson Green

@AndersonGreen Não deve importar (já que qualquer idioma que pode abrir um soquete de rede pode falar HTTP), mas o REST é um pseudo-padrão útil.
Reinstale Monica

7
RESTO + JSON seria uma solução razoável
David Hayes

Também concordo que o uso do HTTP para se comunicar permite que praticamente todas as linguagens lá fora interajam com as funções do seu aplicativo.
Only Bolivian Here

30

Eu acho que C ou C ++ seria mais adequado para o seu propósito. Você pode usar SWIG (Wrapper simplificado e gerador de interface) para gerar ligações de idioma a partir da sua API C ou C ++.

SWIG é uma ferramenta de desenvolvimento de software que conecta programas escritos em C e C ++ com uma variedade de linguagens de programação de alto nível. SWIG é usado com diferentes tipos de linguagens de destino, incluindo linguagens de script comuns como Perl, PHP, Python, Tcl e Ruby. A lista de idiomas suportadostambém inclui linguagens sem script, como C #, Common Lisp (CLISP, Allegro CL, CFFI, UFFI), linguagem D, Go, Java incluindo Android, Lua, Modula-3, OCAML, Octave e R. Também vários esquemas interpretados e compilados implementações (Guile, MzScheme / Racket, Chicken) são suportadas. O SWIG é mais comumente usado para criar ambientes de programação interpretados ou compilados de alto nível, interfaces de usuário e como uma ferramenta para testar e criar protótipos de software C / C ++. O SWIG é normalmente usado para analisar interfaces C / C ++ e gerar o 'código de cola' necessário para que os idiomas de destino acima chamem no código C / C ++. O SWIG também pode exportar sua árvore de análise na forma de expressões XML e Lisp. O SWIG é um software livre e o código que o SWIG gera é compatível com projetos comerciais e não comerciais ...


32
C ++ seria uma escolha terrível. Existem inúmeros problemas com ele: dependência de uma biblioteca de tempo de execução, ABI não especificada (especialmente desconcertante) etc. Gerar ligações a partir de cabeçalhos C ++ é proibitivamente complicado. SWIG é uma coisa bastante limitada. Veja toda a infraestrutura complicada em torno, por exemplo, das ligações Python Qt.
SK-logic

14
@ SK-logic: Na verdade, não. C precisa de uma lib de tempo de execução, assim como C ++. O ABI pode ser controlado em C ++ via, extern "C"portanto, é compatível com C no exterior. Assim, você tem as vantagens internas do C ++ (tipo mais elevado-segurança, bibliotecas), mas as vantagens externas de C (de facto ABI padrão)
MSalters

3
@ SK-logic A ABI não especificada é simplesmente um problema resolvido, consulte SWIG, Boost.Python e uma série de outras ligações de linguagem.
22912 Konrad Rudolph

3
@MSalters não se esqueça sobre exceções e sua não-workiness geral através das fronteiras da biblioteca
sehe

3
-1 para sugestão de C ++. C é fácil, C ++ torna as coisas desnecessariamente difíceis.
Ernest Friedman-Hill

23

Existem basicamente duas maneiras:

  • uma API C. Praticamente todas as linguagens existentes carregarão uma biblioteca C e chamarão suas funções. Como você faz isso depende do idioma de origem.
  • um mecanismo RPC de algum tipo. Pode ser uma API REST executando HTTP ou uma interface binária executando um soquete. A menos que você opte pelo menor mecanismo de denominador comum (por exemplo, um soquete), corre o risco de não ter rotinas de acesso ao cliente (por exemplo, alguns idiomas não têm os clientes SOAP certos para chamar uma API implementada usando SOAP, ou há problemas de interoperabilidade). Atenha-se ao mais simples, uma interface HTTP / REST ou um soquete. Os soquetes têm a vantagem de não precisarem de um servidor HTTP para expor a interface aos clientes e podem ser executados mais facilmente no mesmo servidor que o cliente com melhor desempenho.

O trabalho necessário para essas alterações, dependendo do sistema usado, por exemplo, uma interface de soquete funcionará, mas as bibliotecas do lado do cliente tendem a ter um nível mais baixo em comparação às bibliotecas http.

Você pode tentar encontrar uma biblioteca de rede que ofereça suporte a todos os idiomas que deseja usar e implementar a API em termos dessa biblioteca - por exemplo, o uso do ZeroMQ oferece muita flexibilidade, para que você escreva sua API usando as interfaces do ZeroMQ e qualquer idioma que queira chamar sua API deve usar a biblioteca do cliente ZeroMQ para fazer isso. Escolha uma biblioteca que ofereça suporte a uma ampla variedade de idiomas e permita a comunicação em processo e fora de processo para obter o melhor desempenho.


Então, que medidas eu precisaria tomar se também quisesse escrever a API em vários idiomas? (No meu caso, essas línguas seria Javascript, C ++ e Java.)
Anderson Verde

Devo apenas escrever 3 APIs RESTful separadas para cada um dos idiomas?
Anderson Green

Você escreve um invólucro nativo em cada um desses idiomas que lida com o carregamento e a chamada da dll C subjacente. Ou escreva em C ++ e use SWIG para fazer isso por você. Se você estiver usando uma API REST, o mesmo se aplica, escreva uma única API e depois 3 wrappers, mas se você estiver escrevendo uma API REST, cada idioma poderá chamar a API REST diretamente - não se preocupe com um invólucro.
Gbjbaanb

A dll (biblioteca vinculada dinamicamente) seria compatível com qualquer plataforma além do Windows? Preciso de compatibilidade entre plataformas aqui.
Anderson Green

não, você precisará recompilar para outras plataformas. O Linux, por exemplo, usa .so em vez de .dll. É necessária apenas uma recompilação direta, sem alterações (ou muito pequenas) no código.
Gbjbaanb

12

Se o desempenho e a latência de chamadas não forem um problema, considere fornecer uma interface abrangente de linha de comando (provavelmente, usando uma linguagem de script em cima dela). O ImageMagick pode ser um bom exemplo dessa "API". Outro bom exemplo é o kit de ferramentas Tk.


Qual linguagem de script e / ou linguagem de programação você recomendaria para criar uma interface de função externa de linha de comando? Além disso, você encontrou algum exemplo concreto dessas interfaces?
Anderson Green

@ AndersonGreen, qualquer idioma com metaprogramação decente é aceitável para esse fim. Por exemplo, Scheme, MetaLua, vários outros Lisps incorporáveis, Tcl. Você também pode implementar facilmente sua própria linguagem de comando. Muitos sistemas CAD / CAE funcionam dessa maneira. Um Tk já mencionado é outro exemplo típico.
SK-logic

Para usar uma interface de linha de comando dessa maneira, você obteria a saída do console para um comando específico (como whoamino Ubuntu para obter o nome de usuário) ou você tinha outra coisa em mente?
Anderson Green

@AndersonGreen, canalizar stdin e stdout deve ser suficiente na maioria dos casos.
SK-logic

5

Por API, o que exatamente você quer dizer?

Em muitas plataformas, você poderia vincular a uma DLL ou construção semelhante, mas teria que ser recompilado para um destino nativo específico (Intel / ARM) ou endianness ainda se qualificaria? Uma interface binária específica ainda pode ter dificuldades com certos idiomas devido a problemas ou construções de tipo de dados (ponteiros tentando retornar para idiomas que não os suportam bem), portanto, você também deve considerar o design da própria API para não excluir alguns idiomas ou fazer com que esses idiomas sejam pesados.

Algo portátil como C e uma interface baseada em pontos de extremidade binários em uma DLL podem ser bons e geralmente acessíveis na maioria das plataformas e na maioria dos idiomas, mas pode precisar ser compilado de forma diferente e / ou oferecido em diferentes sabores ou vinculado a diferentes bibliotecas estáticas.

Parece-me que a escolha do idioma em que você escreve sua biblioteca ou serviço ou o que quer que seja, por definição, não é intrínseca à questão até que você dê mais informações sobre a plataforma / serviço que a API expõe. Se você puder assumir que uma pilha de rede está disponível e o desempenho no nível da chamada da função vinculado diretamente não for um requisito, a API poderá ser facilmente baseada em HTTP com algum tipo de correção para que o idioma do cliente torne as solicitações transparentes.

Eu acho que, em geral, essa questão é muito ampla para ser útil no mundo real, porque você não deu indicação sobre que tipo de API pode ser adequado, dado o tipo de serviço que está sendo oferecido.


2

Para adicionar às respostas acima que sugerem o uso de um mecanismo RPC. Você pode usar o Apache Thrift. ( Http://thrift.apache.org/ ). É basicamente uma estrutura RPC.

De acordo com o wiki Thrift:

A estrutura de software Apache Thrift, para desenvolvimento de serviços escaláveis ​​em vários idiomas, combina uma pilha de software com um mecanismo de geração de código para criar serviços que funcionam de maneira eficiente e sem problemas entre C ++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C #, Cacau, JavaScript, Node.js, Smalltalk, OCaml e Delphi e outros idiomas


Como as chamadas de funções estrangeiras podem ser feitas usando o Apache Thrift?
Anderson Green

0

Qualquer idioma escreva um arquivo de texto com a função para chamar params para passar. Faça com que o aplicativo "eu me dou bem com alguém" assista a um diretório e, quando ele vir um processo-call.txt, faça com que ele funcione. Nenhum servidor ou protocolo de rede; mesmo um método de linguagem que não seja de computador pode iniciar as funções. Mesmo uma pessoa poderia apenas criar o arquivo de texto.

O conteúdo pode ter a seguinte aparência:

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

;) você pode esperar uma eternidade para obter uma resposta. Você só precisa enviar alguns bytes para o outro processo, mas tenho certeza de que essa não é a especificação completa.


Parece muito complicado quando você pode ter apenas uma interface de linha de comando + stdin / stdout.
Reinstale Monica

1
Melhor ainda, posso chamar +1, Brendan. Eu nunca vi isso em ação, mas uma vez as pessoas faziam buracos no cartão para transferir os bytes.
Pareshkumar

4
Esta é uma resposta de brincadeira, certo? Nós não fazemos isso aqui.
Ernest Friedman-Hill

Bem, a parte do fdisk e / root é uma piada, mas eu estive envolvido como P&D de plataforma (desenvolvedor e analista) por mais de 5 anos para criar um produto de plataforma que produziu bons resultados na casa dos 10 milhões de dólares. Ele cuspiu milhões de itens físicos entregues (não pdf e e-mails) para o cliente (com arquivos de processamento variando em centenas de MBs por item) usando esse tipo de método REST. Tínhamos um grande fluxo de trabalho de triolgy-SAP-MS Office-PLC Drivewrs-PDF do sistema, todos trabalhando um com o outro e trabalhando bem em conjunto com arquivos de texto UTF-8-texto simples e antigos e um zip com um zip com um zip, e sem sobrecarga de HTTP bs.
Pareshkumar

Posso fazer uma pergunta? Por que ninguém acha que JSON é uma piada? Como é que eu recomendo diferente? Nós poderíamos ter usado json, mas não existia em 2003. XML é muito gordo, mas naquela época esse era o sabor do mês, não a alma mais prática e simples.
Pareshkumar

0

O OpenGL é um bom exemplo do que você descreve - é uma API escrita em C, projetada de maneira fácil para escrever ligações em outros idiomas

  1. As bibliotecas C podem ser chamadas da maioria das linguagens de programação (geralmente como extensões compiladas ou coisas como a ctypesbiblioteca do PyPy, etc.)

  2. Todas as funções aceitam tipos de dados simples como argumentos (booleano, inteiro, ponto flutuante, constantes, matrizes), pois funções que usam ponteiros podem ser difíceis de traduzir para alguns idiomas

  3. Ter seus próprios tipos de dados numéricos, que especificam precisão e sinalização (enquanto int floatetc podem ser diferentes)

A API resultante não é necessariamente a API C mais agradável de usar que você poderia escrever se visasse apenas usuários C. No entanto, isso significa que as funções podem ser quase diretamente expostas a outro idioma (por exemplo, os documentos do PyOpenGL listam as diferenças, a maioria das quais é bastante mínima)

Além dessa API detalhada, você pode escrever mais wrappers "amigáveis ​​ao desenvolvedor" em torno disso (estruturas de jogos e outras)

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.