Tenho uma DLL proprietária que comunica-se com uma balança e preciso extrair informações desta balança (peso, por exemplo) através desta DLL. Dando uma passada pela net achei vários tutoriais sobre JNI, onde os passos para efetuar a comunicação eram: gerar .class, gerar ficheiro .h, criar o arquivo .c baseado no .h e depois gerar a DLL. Contudo, tenho apenas as assinaturas das funções desta DLL (desenvolvida em C). Como posso efetuar esta comunicação? Criei uma espécie de helloworld usando jni tentando comunicar-se com a dll. Pelo que pude perceber, a minha classe java carrega a dll, mas na hora de chamar o método dá erro. Segue abaixo o código seguido do erro. Por favor, alguém me ajude…
public class HelloWorld {
public native Boolean SalvaParametrosBalanca(int Balança, int Modelo,
int Porta, int BaudRate);
static {
System.loadLibrary("dll/PcScale");
}
public static void main(String[] args) {
HelloWorld hello = new HelloWorld();
Boolean teste = hello.SalvaParametrosBalanca(0, 0, 0, 0);
System.out.println(teste.booleanValue());
}
}
Exception in thread “main” java.lang.UnsatisfiedLinkError: SalvaParametrosBalanca
at HelloWorld.SalvaParametrosBalanca(Native Method)
at HelloWorld.main(HelloWorld.java:12)
Eu recomendo você fazer uma biblioteca (.dll / .so) para mapear / expor as funcionalidades que você precisa, e, então, utilizar o SWIG (google it) para gerar os bindings. JNI é frustrante comparado à interface nativa de outras linguagens, como Python e Lua .
estou agora tentando usar JNA sim… É realmente muito mais fácil…
MAS (sempre existe um MAS, rsrs),
estou tendo dificuldades em ler um retorno ‘char*’ do c…
estou pegando este retorno como String, mas o String é populado apenas com o primeiro caracter da char*
exemplo:
no c, o cha* é:
“Abacate”
no Java fica:
“A”
estou agora tentando mudar o meu .c para .cpp para assim poder usar AnsiString por exemplo…
Mas infelizmente não tenho nada para acrescentar, pelo contrário, tenho mais dúvidas. Por exemplo, com o JNA eu consigo invocar um método de uma DLL proprietária, é isso?
No caso do retorno desse método ser um Recordset do VB, como fica a interpretação?
public boolean InicializaBalanca(int balanca) {
Balanca dll = Balanca.INSTANCE;
boolean teste = dll.InicializaBalanca(0);
return teste;
}
}
Mas quando tento chamar o método em uma classe de teste dá o seguinte erro:
Exception in thread “main” java.lang.UnsatisfiedLinkError: Cannot locate function ‘InicializaBalanca’
at com.sun.jna.NativeLibrary.getFunctionAddress(NativeLibrary.java:228)
at com.sun.jna.Function.(Function.java:143)
at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:212)
at com.sun.jna.Library$Handler.invoke(Library.java:165)
at $Proxy0.InicializaBalanca(Unknown Source)
at BalancaImpl.InicializaBalanca(BalancaImpl.java:7)
at TestaDLL.main(TestaDLL.java:5)
Dentro do meu projeto no eclipse existe a pasta dll onde está a dll da qual desejo usar as funções.
Acho que já tenho a resposta para a minha pergunta…
Vasculhando os arquivos dessa dll proprietária, encontrei o arquivo .h dela. No .h, o método boolean InicializaBalanca(int balanca) está com a seguinte estrutura:
Problema Resolvido! Na verdade o problema estava entre o monitor e a cadeira! O manual da DLL que eu estava usando era antigo. Quando verifiquei o arquivo .h da DLL percebi isso. A assinatura do método estava errada. Quando setei, na minha interface java, a assinatura do método com base no arquivo .h deu certo!
JNA é muito mais simples mesmo! Obrigado a todos!