Access to the DLL library made in Delphi from Java

Asked

Viewed 1,899 times

35

I am developing a tool for biometric recognition using the SDK provided in DLL format, developed in Delphi. For DLL access from Java, I am using JNA.

The digital template (the most important part) is an object that refers to this excerpt (in Delphi):

type
  CIS_Digital = packed record
    intSize: integer;
    pDigital: Pointer
  end;

pCIS_Digital = ^CIS_Digital;

How to develop something equivalent in Java?


Basically, I need to call the following DLL functions:

SDK_CIS_Iniciar(int cnpj, int detectaFake);
SDK_CIS_LerDigital(pCIS_Digital digital);
SDK_CIS_CompararDigital(pCIS_Digital amostra1, pCIS_Digital amostra2);
SDK_CIS_Finalizar();

Looking at the example provided, developed in Delphi, I saw that the object pCIS_Digital, past SDK_CIS_LerDigital() and SDK_CIS_CompararDigital(), is the type (type) declared in the code snippet above.

In the same example, before calling the method SDK_CIS_LerDigital(), the object pCIS_Digital is instantiated and goes empty where it is then "filled" through the function.

The reader is the Techmag Bioflex, which is based on Futronic readers (FS-80).

Searching, I saw that the object pCIS_Digital (from the code snippet), access the memory to read the information the reader writes to it.

After a lot of research, think that I must develop some equivalent object in Java, extending from the classes Structure or Memory, jna.

Lista de funções do SDK fornecido


Update: Information about my code

I read and store my fingerprint twice using the method SDK_CIS_LerDigital, then compare the two using the method SDK_CIS_CompararDigital, who always returns 0 (unexecuted command).

"Printei" the objects intSize and pDigital after reading the digital, intSize returns 0 and pDigital returns null.

Interface with DLL methods:

public interface SDK_CIS extends StdCallLibrary {

static SDK_CIS INSTANCE = (SDK_CIS) Native.loadLibrary("SDK_CIS", SDK_CIS.class);

    public String SDK_CIS_Versao();

    public String SDK_CIS_Retorno(int resposta);

    public int SDK_CIS_Iniciar(long cnpj, int fake);

    public int SDK_CIS_Finalizar();

    public int SDK_CIS_LerDigital(CIS_Digital.ByReference digital);

    public int SDK_CIS_CancelarLeitura();

    public int SDK_CIS_CompararDigital(CIS_Digital.ByReference pAmostra1, CIS_Digital.ByReference pAmostra2);
}

Class extending Structure, referring to the Cis_digital object:

public class CIS_Digital extends Structure {

    public static class ByReference extends CIS_Digital implements Structure.ByReference {}

    public int intSize;
    public Pointer pDigital;

    @Override
    protected List<String> getFieldOrder() {
        return Arrays.asList("intSize", "pDigital");
    }
}

Method responsible for reading twice any digital and comparing them:

public void leEcomparaDigitais() {

        SDK_CIS leitor = SDK_CIS.INSTANCE;

        try {
            // TROQUEI MEU CNPJ POR ZEROS, PARA NÃO EXPOR MINHA LICENÇA    
            leitor.SDK_CIS_Iniciar(Long.parseLong("00000000000000"), 0);

            CIS_Digital.ByReference amostra1 = new CIS_Digital.ByReference();

            leitor.SDK_CIS_LerDigital(amostra1);

            try {
                // AGUARDA 1 SEGUNDO PARA LER PELA SEGUNDA VEZ
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            CIS_Digital.ByReference amostra2 = new CIS_Digital.ByReference();

            leitor.SDK_CIS_LerDigital(amostra2);

            int resp = leitor.SDK_CIS_CompararDigital(amostra1, amostra2);

            // EXIBE RESPOSTA
            // 0 -> COMANDO NAO EXECUTADO
            // 1 -> COMANDO EXECUTADO COM SUCESSO
            System.out.println(resp);

        } finally {
            leitor.SDK_CIS_Finalizar();
        }
    }
  • 1

    Please check function output leitor.SDK_CIS_LerDigital(amostra1);. The problem may be in reading and you are not checking the return

  • Hello! I called the Sdk_cis_version method and it prints the SDK version (2014.001.02.1404).

  • This is the first time I work with access to Dlls. I have no idea what the Calling Convention of the SDK_CIS dll is about. I will search it. Thanks again.

  • In a quick search, I found the following information: Based on the Pascal Programming language’s Calling Convention, the Parameters are pushed on the stack in left-to-right order (Opposite of cdecl), and the callee is Responsible for Balancing the stack before Return. This Calling Convention was common in the following 16-bit Apis: OS/2 1.x, Microsoft Windows 3.x, and Borland Delphi version 1.x. Modern versions of the Windows API use stdcall, which still has the callee Restoring the stack as in the Pascal Convention, but the Parameters are now pushed right to left.

  • Lerdigital reton 1. (1 = command executed successfully).

  • amostra1.intSize always returns 0?

  • Yes, @Eprogrammernotfound. intSize always 0 and pDigital always null. =(

  • You have a Delphi version of this system that is working?

  • I do, @Eprogrammernotfound. With the source and everything.

  • tries to run this in jar in Delphi( programs intended in java and in Delphi flames a jar.

  • I saw this post here on SOF in English, but the answer code is in Portuguese. You may be able to reach the respondent via chat: http://stackoverflow.com/questions/30945826/function-mapping-delphi-dll-with-java-jna

  • Is the DLL 32 or 64 bit? What version of java do you want to use (example: 1.7 32bits, 1.8 64bits) ? If you need to recompile the DLL (in Delphi), you can change its source code?

  • 1

    A slightly different suggestion, you could make a c/c++ interface with a dll and implement the methods in Java using JNI. Java+Delphi using JNI: http://www.linhadecodigo.com.br/artigo/747/jni-interacao-java-e-outras-linguagens.aspx; Delphi DLL and c++: https://sergworks.wordpress.com/2013/12/consuming-delphi-interfaces-in-dephi-and-c/; JNI: https://www3.ntu.edu.sg/home/ehchua/programming/java/JavaNativeInterface.html.

  • so I know you should call the jar in Delphi, that jar should generate an output for you then just break the string

Show 9 more comments

1 answer

2

This may be an error due to calling convention of the functions in the DLL.

Assuming you have the original DLL source code in Delphi, you can change the calling convention functions including the clause stdcall at the end of the definition, for example:

function foobar( x: Integer ): Integer; stdcall;

I hope it will be useful!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.