Jna

Estou querendo usar uma dll feita em C++. Dentro dela tem varios metodos com parameto, um deles como exemplo abaixo:

===========================================================================Função:
void GetDllVersion( )
Sintaxe:
GetDllVersion(char* Versao)
Objetivo:
Esta função escreve na área apontada por Versao, a versão atual da dll, em caracteres ASCII.
Argumentos:
char* Versao = ponteiro char para uma área livre de pelo menos 3 bytes.
Valor de retorno:
Não retorna nenhum valor.
===========================================================================Função:
int GetChannel( )
Sintaxe:
GetChannel(HANDLE* AddhCom, int* Erro, int Canal, int Timeout, int Baud, int StopBits, int DataBits, char paridade)
Objetivo:
Esta função aloca um canal serial dentro do Windows. Este canal serial será utilizado durante todo
o processo de comunicação com o CLP.
Argumentos:
HANDLE* AddhCom = Endereço do HANDLE do canal serial.
int* Erro = Endereço onde será retornado o código inteiro do erro, caso ocorra.
int Canal = Valor inteiro que deve valer 1, 2, 3 ou 4, representando o canal COMx.
int Timeout = Valor inteiro que representa o tempo que será esperado para cada
comunicação com o CLP. Valor em milissegundos.
int Baud = Valor que representa a velocidade de comunicação (Baud Rate)
int StopBits = Numero de Stop Bits de cada byte. Pode ser 1 ou 2.
int DataBits = Tamanho do byte de dados da comunicação Pode ser 7 ou 8.
char Paridade = Paridade da comunicação. Pode ser ‘N’ (nenhuma), ‘E’ (par) ou ‘O’
(impar)
Valor de retorno:
Inteiro. Caso ocorra erro, retorna 0, caso contrário retorna 1.
===========================================================================Função:
int ReleaseChannel( )
Sintaxe:
ReleaseChannel(HANDLE hCom)
Objetivo:
Esta função libera um canal serial previamente alocado.
Argumentos:
HANDLE hCom = HANDLE do canal serial.
Valor de retorno:
Inteiro. Caso ocorra erro, retorna 0, caso contrário retorna 1.

Implementei essas funcoes no java e tento manipular. Mai exemplo ReleaseChannel para ver se a porta esta conectada traz somente 0, mesmo conectando ela.

Muito Obrigado

Olá, ricardocaoj!!

Eu imagino que não tenha nada de errado com o JNA, porque, pelo que eu vi, o Java encontra e executa a função normalmente.

Como o seu problema é que a função não retorna o valor que vc espera, vc pode tentar testar essa função direto no C, fazendo aparecer os resultados no console.

Espero ter ajudado

Oi elingela, essa função funciona normalmente no VB.net mais gostria de desenvolver o sistema em java. A dificulade esta colocar os metodos que tem no C para java.

Exemplo:

int ReleaseChannel( )
Sintaxe:
ReleaseChannel(HANDLE hCom)

no Java depois de usar JNA

public abstract int ReleaseChannel();

E assim executar o codigo da dll.

A dificuldade estaria na implementação dos dados. Teria algum exemplo?

Muito Obrigado

Alguém se Habilita.

cara,
ja utilizei JNA e funcionou perfeitamente, o esquema dele é vc tem que ter um metodo java que tenha o msm nome do metodo que vc implementou no C++.

qualquer duvida posta ai.

t+

[quote=ricardocaoj]Oi elingela, essa função funciona normalmente no VB.net mais gostria de desenvolver o sistema em java. A dificulade esta colocar os metodos que tem no C para java.

Exemplo:

int ReleaseChannel( )
Sintaxe:
ReleaseChannel(HANDLE hCom)

no Java depois de usar JNA

public abstract int ReleaseChannel();

E assim executar o codigo da dll.

A dificuldade estaria na implementação dos dados. Teria algum exemplo?

Muito Obrigado

[/quote]

Voce precisa mapear um tipo compatível entre as duas linguagens senão não funcionará mesmo. Em caso de apontadores(valores referenciados) você pode usar Object. Os tipos primitivos possuem limites, como o caso de um inteiro no java possuir 32 bits sinalizados, e em c++ eu tenho inteiros que podem chegar a 64 bits sinalizados ou não.

Você precisa olhar a documentação do compilador que criou a dll e ver qual é o tipo para criar uma solução adequada.

aqui tem uma parte da documentação

===========================================================================Função:
void GetDllVersion( )
Sintaxe:
GetDllVersion(char* Versao)
Objetivo:
Esta função escreve na área apontada por Versao, a versão atual da dll, em caracteres ASCII.
Argumentos:
char* Versao = ponteiro char para uma área livre de pelo menos 3 bytes.
Valor de retorno:
Não retorna nenhum valor.
===========================================================================Função:
int GetChannel( )
Sintaxe:
GetChannel(HANDLE* AddhCom, int* Erro, int Canal, int Timeout, int Baud, int StopBits, int DataBits, char paridade)
Objetivo:
Esta função aloca um canal serial dentro do Windows. Este canal serial será utilizado durante todo
o processo de comunicação com o CLP.
Argumentos:
HANDLE* AddhCom = Endereço do HANDLE do canal serial.
int* Erro = Endereço onde será retornado o código inteiro do erro, caso ocorra.
int Canal = Valor inteiro que deve valer 1, 2, 3 ou 4, representando o canal COMx.
int Timeout = Valor inteiro que representa o tempo que será esperado para cada
comunicação com o CLP. Valor em milissegundos.
int Baud = Valor que representa a velocidade de comunicação (Baud Rate)
int StopBits = Numero de Stop Bits de cada byte. Pode ser 1 ou 2.
int DataBits = Tamanho do byte de dados da comunicação Pode ser 7 ou 8.
char Paridade = Paridade da comunicação. Pode ser ‘N’ (nenhuma), ‘E’ (par) ou ‘O’
(impar)
Valor de retorno:
Inteiro. Caso ocorra erro, retorna 0, caso contrário retorna 1.

Exemplo usando JNA na implementacao da versao da dll.

package projetosupervisorio;


import projetosupervisorio.libs.Atos2Pc;
import com.sun.jna.Native;
import projetosupervisorio.net.Estrutura;

public class Conexao {

   
    public static void main(String args[]){
        Atos2Pc lib = (Atos2Pc) Native.loadLibrary("Atos2Pc", Atos2Pc.class);
        Estrutura estrutura = new Estrutura();
        lib.GetDllVersion(estrutura);
    
        System.out.print(estrutura.Versao);
 
    }

    private static String bs2(byte[] Versao) {
         int len = 0;
        while (Versao[len] != 0)
          ++len;
         return new String(Versao, 0, len);
    }


}
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.tularte.modelo;

import com.sun.jna.Structure;

/**
 *
 * @author dasilvr
 */
public class Estrutura extends Structure {
    public int hCom;
    public int Erro;   
    public int CanalOk;
    public byte Versao[] = {0,0,0}; 
    
}
package projetosupervisorio.libs;

import com.sun.jna.Library;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.org.apache.xerces.internal.impl.io.ASCIIReader;
import java.util.Locale;
import com.sun.jna.win32.StdCallLibrary;
import projetosupervisorio.net.Estrutura;

public interface Atos2Pc extends StdCallLibrary {

    public void GetDllVersion(Estrutura result);


    }        

        
	
}

Exemplo em VB

?	public class CLP
    {

        #region Variáveis Globais

        public int hCom=0;                            // Handle para o canal serial
        public int Erro=0;                            // Codigo do ultimo erro ocorrido

        private int timeout=0;                         // Timeout para cada comunicação - em milissegundos
        
        private int Address=0;                         // Numero do clp na rede Atos
        private string TXBuffer="";                     // Retorna o frame enviado para o clp
        private string RXBuffer="";                     // Retorna o frame recebido do clp
        public byte ValorB=0;                         // Byte utilizado para operações de liga/desliga estados internos
        public UInt16 ValorM = 0;                     // Área de 2 bytes de memória para operações de envia/pede variável de maneira genérica
        public byte[] ValorMB = { 0,0,0,0,0,0,0,0 };  // Área de 8 bytes de memória para operações de envia/pede bloco
        public int ValorI=0;                          // Número inteiro para enviar/receber variável do clp em formato binário
        public int ValorIBCD=0;                       // Número inteiro para enviar/receber variáveis do clp no seu formato default (BCD)

        public int CanalOk=0;                        // Vai indicar se o canal serial foi aberto com sucesso
        private byte[] Versao = {0,0,0};         // Recebe a versao da dll
        #endregion

        #region Mapeamento das funções em código não gerenciado
        /* Mapeamento das funções em código não gerenciado */
        [DllImport("atos2pc.dll")]
        private static extern void GetDllVersion(byte[] Versao);
        [DllImport("atos2pc.dll")]
        private static extern int GetChannel(ref int hCom, ref int Erro, int Canal, int Timeout, int BaudRate, int StopBits, int DataBits, byte Paridade);
        [DllImport("atos2pc.dll")]
        private static extern int ReleaseChannel(int hCom);
        [DllImport("atos2pc.dll")]
        private static extern int EnviaAck(int PlcAddress, int hCom, int Timeout, ref int Erro, string TXBuffer, string RXBuffer);
        [DllImport("atos2pc.dll")]
        private static extern int PedeByte(int PlcAddress, int MemoryAddress, ref byte ValorB,int hCom,int Timeout, ref int Erro, string TXBuffer, string RXBuffer);
        [DllImport("atos2pc.dll")]
        private static extern int EnviaByte(int PlcAddress, int MemoryAddress, byte ValorB, int hCom, int Timeout, ref int Erro, string TXBuffer, string RXBuffer);
        [DllImport("atos2pc.dll")]
        private static extern int PedeVar(int PlcAddress, int MemoryAddress, ref UInt16 ValorM, int hCom, int Timeout, ref int Erro, string TXBuffer, string RXBuffer);
        [DllImport("atos2pc.dll")]
        private static extern int EnviaVar(int PlcAddress, int MemoryAddress, byte[] ValorM, int hCom, int Timeout, ref int Erro, string TXBuffer, string RXBuffer);
        [DllImport("atos2pc.dll")]
        private static extern int PedeVarInt(int PlcAddress, int MemoryAddress, ref int ValorI, int hCom, int Timeout, ref int Erro, string TXBuffer, string RXBuffer);
        [DllImport("atos2pc.dll")]
        private static extern int EnviaVarInt(int PlcAddress, int MemoryAddress, int ValorI, int hCom, int Timeout, ref int Erro, string TXBuffer, string RXBuffer);
        [DllImport("atos2pc.dll")]
        private static extern int PedeVarIntBcd(int PlcAddress, int MemoryAddress, ref int ValorIBcd, int hCom, int Timeout, ref int Erro, string TXBuffer, string RXBuffer);
        [DllImport("atos2pc.dll")]
        private static extern int EnviaVarIntBcd(int PlcAddress, int MemoryAddress, int ValorIBcd, int hCom, int Timeout, ref int Erro, string TXBuffer, string RXBuffer);
        [DllImport("atos2pc.dll")]
        private static extern int PedeBloc(int PlcAddress, int MemoryAddress, int Quantidade, ref byte[] ValorMB, int hCom, int Timeout, ref int Erro, string TXBuffer, string RXBuffer);
        [DllImport("atos2pc.dll")]
        private static extern int EnviaBloc(int PlcAddress, int MemoryAddress, int Quantidade, byte[] ValorMB, int hCom, int Timeout, ref int Erro, string TXBuffer, string RXBuffer);
        #endregion

        #region Métodos expostos pela classe CLP
        public CLP(Serial SerialPort, int DefaultTimeout, int Address)
        {
            // PLC address
            this.Address = Address;

            // Timeout for PLC communications
            this.timeout = DefaultTimeout;

            this.CanalOk = GetChannel(ref this.hCom, ref this.Erro, (int)SerialPort.Channel, this.timeout,(int)SerialPort.BaudRate, (int)SerialPort.StopBits, (int)SerialPort.DataBits, (byte)SerialPort.Parity);
        }
        ~CLP()
        {
            ReleaseChannel(this.hCom);
        }
        public string GetDLLVersion()
        {
            ASCIIEncoding ascii = new ASCIIEncoding();
            GetDllVersion(this.Versao);
            return (ascii.GetString(this.Versao));
        }
        /// <summary>
        /// Testa comunicação com o CLP
        /// </summary>
        /// <returns>TRUE=Comunicação OK / FALSE=Falha na comunicação</returns>
        public bool SendAck()
        {
            try
            {
                if (1 == EnviaAck(this.Address, this.hCom, this.timeout, ref this.Erro, this.TXBuffer, this.RXBuffer))
                {
                    return true;
                }
                else
                    return false;
            }
            catch
            {
                return false;
            }
        }

        public bool GetByte(int MemoryAddress)
        {
            if (1 == PedeByte(this.Address, MemoryAddress, ref this.ValorB, this.hCom, this.timeout, ref this.Erro, this.TXBuffer, this.RXBuffer))
            {
                return true;
            }
            else
                return false;
        }
        public bool SendByte(byte B, int MemoryAddress)
        {
            if (1 == EnviaByte(this.Address, MemoryAddress, B, this.hCom, this.timeout, ref this.Erro, this.TXBuffer, this.RXBuffer))
            {
                return true;
            }
            else
                return false;
        }
        public bool GetVar(int MemoryAddress)
        {
            byte[] var = {0,0};
            byte[] inv_var = { 0, 0 };
            UInt16 val = 0;
            if (1 == PedeVar(this.Address, MemoryAddress, ref val, this.hCom, timeout, ref this.Erro, this.TXBuffer, this.RXBuffer))
            {
                var = BitConverter.GetBytes(val);
                inv_var[0] = var[1]; inv_var[1] = var[0];
                this.ValorM = BitConverter.ToUInt16(inv_var, 0);
                return true;
            }
            else
                return false;
        }
        public bool SendVar(ushort Var, int MemoryAddress)
        {
            byte[] var = { 0, 0 };
            byte[] inv_var = { 0, 0 };

            var = BitConverter.GetBytes(Var);

            inv_var[0] = var[1];
            inv_var[1] = var[0];
            
            if (1==EnviaVar(this.Address, MemoryAddress, inv_var, this.hCom, this.timeout, ref this.Erro, this.TXBuffer, this.RXBuffer))
            {
                return true;
            } else
                return false;
        }
        public bool GetIntVar(int MemoryAddress)
        {
            if (1 == PedeVarInt(this.Address, MemoryAddress, ref this.ValorI, this.hCom, this.timeout, ref this.Erro, this.TXBuffer, this.RXBuffer))
            {
                return true;
            }
            else
                return false;
        }
        public bool SendIntVar(int Var, int MemoryAddress)
        {
            if (1 == EnviaVarInt(this.Address, MemoryAddress, Var, this.hCom, this.timeout, ref this.Erro, this.TXBuffer, this.RXBuffer))
            {
                return true;
            }
            else
                return false;
        }
        public bool GetBCDIntVar(int MemoryAddress)
        {
            if (1 == PedeVarIntBcd(this.Address, MemoryAddress, ref this.ValorIBCD, this.hCom, this.timeout, ref this.Erro, this.TXBuffer, this.RXBuffer))
            {
                return true;
            }
            else
                return false;
        }
        public bool SendBCDIntVar(int Var, int MemoryAddress)
        {
            if (1 == EnviaVarIntBcd(this.Address, MemoryAddress, Var, this.hCom, this.timeout, ref this.Erro, this.TXBuffer, this.RXBuffer))
            {
                return true;
            }
            else
                return false;
        }
        public bool GetBlock(int MemoryAddress, int Length)
        {
            if (1 == PedeBloc(this.Address, MemoryAddress, Length, ref ValorMB, this.hCom, this.timeout, ref this.Erro, this.TXBuffer, this.RXBuffer))
            {
                return true;
            }
            else
                return false;
        }
        public bool SendBlock(int MemoryAddress, byte[] Block, int Length)
        {
            if (1 == EnviaBloc(this.Address, MemoryAddress, Length, Block, this.hCom, this.timeout, ref this.Erro, this.TXBuffer, this.RXBuffer))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        /// <summary>
        /// Liga ou desliga um EI (estado interno) do CLP.
        /// </summary>
        /// <param name="MemoryAddress">Endereço do EI</param>
        /// <param name="on">TRUE=ligado / FALSE=desligado</param>
        /// <returns></returns>

Gostaria da implementacao de apenas um metodo.

passe seu email por favor

Ricardo Silva