Pergunta

Atualmente estou desenvolvendo um projeto escrito em Java. Temos um monte de algoritmos escritos em C / C ++ (pelo menos algumas centenas) que precisam ser incorporadas em nosso projeto. Nossas duas opções são para usar JNI para chamar esse código, ou de reescrever todos os algoritmos em Java.

Estou ciente das consequências do uso de JNI, pode abrir todo um novo conjunto de problemas, é por isso que reescrever todo o código em Java é mesmo a ser considerado. Mas o pensamento de reescrevê-lo parece ... errado. Os algoritmos foram testados e trabalho, tanto quanto eu sei, eles são apenas no idioma errado.

Nesta situação, seria JNI tornar esta tarefa fácil? Ou ele poderia causar mais dor de cabeça do que reescrever o código em Java faria?


EDIT # 1: Perguntas relacionadas - Utilidade da JNI


EDIT # 2: FYI - projeto Nossa Java não é feito para ser portátil de qualquer forma. Isso pode eliminar uma das desvantagens da JNI em que supostamente reduz a portabilidade.

Foi útil?

Solução

A resposta simples é, se o código vai ser chamado de um monte E o desempenho é importante, em seguida, convertê-lo ao longo de Java.

As respostas mais complexas são:

  • Se a biblioteca facilmente envolto em JNI, em seguida, ir com JNI
  • Se os testes que você tem para o código C / C ++ facilmente convertidos até Java, em seguida, ir para a porta

Eu faria o seguinte:

  • tomar um dos algoritmos e envolvê-la em JNI
  • tomar o mesmo algoritmo e convertê-lo em Java
  • ver qual é mais uma dor de fazer
  • Se a velocidade é importante, em seguida, perfil ambas as versões e ver qual deles é aceitável.

Outras dicas

Eu acho que as mentiras resposta na quantidade de acoplamento haveria entre o código java chamar eo código C / C ++ invocado e no nível de esforço a reescrita implicaria. Se o seu código C leva alguns inteiros, faz algum cálculo cabeludo, e retorna outra int. Use JNI. Se há um monte de volta complexo e para trás, mas os algoritmos são razoavelmente simples, reescrever 'em. A linha de falha é a conexão JNI. Se isso vai ser complexo, você pode acabar escrevendo código interface mais JNI que você faria algoritmo de código para uma reescrita.

Se os "algoritmos" são bem-embalados, talvez seja possível criar um código de cola automática, através de JNI? Isso seria reduzir o risco de erros (criando centenas de componentes individuais sons manualmente arriscado), e fazer o independente custo do número de algoritmos para adicionar, mais ou menos.

Reescrevendo centenas de sons componentes muito arriscado, eu recomendaria definitivamente pelo menos investigar JNI mais de perto pela primeira vez.

Quais são os requisitos de I / O é que os algoritmos têm em relação ao resto do projeto? Se eles são bastante baixo acoplamento, talvez seria possível executá-los como free-standing programas separados, invocadas como sub-processos de Java e usando por exemplo stdio para compartilhar dados?

Eu acho que você vai achar que usando JNI não é tão assustador quanto parece antes de mergulhar dentro. Há algumas importantes trade-offs e limitações, mas em JNI geral funciona bem e é razoavelmente fácil de alavancagem como você pretende.

Como outros já disse que o melhor caso para JNI é:

  • código nativo Complex (pontos de bônus se que o código já provou muito confiável)
  • back-e-vem Minimal entre Java e código nativo (que pretende minimizar as viagens através da camada JNI)
  • interface de chamada razoavelmente simples para o código nativo (ou também de volta para Java Se você é necessidades código nativo para métodos de alavancagem objetos Java /)

É definitivamente possível automatizar ou pseudo-automatizar a criação de uma camada JNI para um conjunto razoavelmente estruturado de componentes nativos. Isso seria vale a pena se o número de componentes de envoltório é grande.

A boa notícia com JNI é que ele deve ser simples para você construir e testar esta interface, por exemplo, você deve ser capaz de casos de teste de escrita de Java que exploram existentes comportamento do algoritmo e se existem problemas que provavelmente seria na própria camada de JNI e não os algoritmos (dada a sua confiança na aplicação nativa).

Reescrevendo um grande número de algoritmos de C / C ++ em Java parece muito mais arriscado para mim do que usando JNI. Sem conhecer os detalhes é difícil de avaliar, é claro, mas há diferenças sutis entre as tecnologias que eu poderia imaginar impactando a implementação real de um algoritmo, para não mencionar apenas o esforço de engenharia pura e risco de erro.

A consideração final é vida futura destes algoritmos ou componentes relacionados. É o conjunto de algoritmos mais ou menos completa, ou você está continuando a acrescentar? De qualquer maneira, há uma razão desenvolvimento manutenção e / ou futuro forte para favorecer uma tecnologia em detrimento do outro? Por exemplo, se tudo o resto é em Java e todos os novos algoritmos estará em Java e quase todos na equipe é quase sempre a codificação em Java, reimplementar em Java começa a parecer mais atraente a longo prazo.

No entanto, mesmo com o que disse, trunfos trabalho consistente. Para um grande número de componentes nativos que funcionem bem eu ainda estaria inclinado a começar com JNI mesmo se você estava indo para transição para Java a longo prazo.

Eu ainda considerar seriamente indo para JNI, especialmente se você é capaz de minimizar o número de interfaces de língua cruz.

Se, por exemplo, há uma pilha inteira de funções C que todos têm as mesmas entradas e saídas, mas apenas fazer um trabalho diferente nas entradas, enrole que em um único invólucro JNI com um parâmetro adicional para especificar qual algoritmo específico para uso.

Se você pretende projectos de escrita futuros em Java, ao contrário de C / C ++. Eu iria morder a bala agora, e portar o código até java. Quanto mais você esperar o pior que se tornará. A JNI soa atraente neste caso, mas então você terá o problema de alguém ter que manter o código C ++ quando todo mundo está sobre os novos projetos Java divertidas.

Se este é um projeto Java uma vez, então por que você escrevê-lo em Java?

A ponte entre C e Java é caro, por isso, se você tem que passar por um monte de dados e para trás não há nenhuma vitória em chamar C ao longo JNI.

Eu vi JNA listado como uma alternativa razoável à JNI com muito menos dor para chamar métodos em uma DLL / biblioteca compartilhada de Java em uma reflexão como caminho. Eu não tentei ainda.

Você pode querer considerar compilar o código C como um binário Linux MIPS que pode ser interpretado em Java. Razoavelmente rápido, um pouco difícil de configurar corretamente. Consulte http://nestedvm.ibex.org/

Além disso, você pode usar um llvm backend para gcc para compilar com baixo nível bytecodes que pode então ser interpretado em Java. Esta é também a abordagem adoptada com o iPhone SDK afaik no Mac OS X. http://llvm.org/

pós receint de Leia Joel em " pagar as suas dívida técnica", em seguida, vá em frente e convertê-lo agora ao invés de pagar juros ao longo dos próximos dois anos e, em seguida, pagando-lo.

Talvez as bibliotecas reembalados poderia ser útil em mais lugares assim. Se eles são bastante útil e complexo para fazer você considere mantê-los em C, eles devem ter ainda mais o uso uma vez embalados muito bem em classes reutilizáveis, facilmente distribuíveis e compreensível.

Eu estive nesta situação. Eu sugiro que você se acostumar a usar as estruturas de dados multi-threaded que estão disponíveis em Java. Neste ponto, você não vai querer voltar para suas estruturas de dados C ++ mais.

Você também vai perceber que você pode re-escrever esses algoritmos muito melhor usando técnicas mais atenciosas, melhor polimorfismo, Adapter e assim por diante.

Quando você está sentado no código C / C ++, você está pensando que você quer segurá-la. Você está pensando sobre todo o amor que você colocou nele. Em poucos anos, você vai perceber que, segurando-o e usando JNI que você criou um monstro. Cada vez que você começa um acidente de processo que você vai se arrepender usando JNI. Depois de corrigir o acidente processo, alguém vai querer modificar um algoritmo em C ++ e você vai querer estrangular-los. Eles terão uma desculpa conveniente como "Eu não estou acostumado a Java ainda."

Dê uma olhada em estruturas de dados imutáveis ??em Java. Não pense mesmo sobre a velocidade que esses algoritmos de idade C / C ++ executar. Descobri que meu novo código de longe out-passos qualquer um dos meus antigo código C / C ++.

testes Write unidade. Use NetBeans.

Atenciosamente,

-Stosh

Dê JNI uma tentativa. Então, se depara com qualquer problema que possa reescrever as problemáticas ou envolva chamadas JNI com webservices e implantá-los em diferentes caixas ou caixas virtuais.

Se isto é somente para Windows, e eles já estão em um DLL, talvez JNA seria de uso. (Se o desempenho bater para chamadas de função através de JNA não é tão ruim)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top