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.
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();
}
}
Please check function output
leitor.SDK_CIS_LerDigital(amostra1);
. The problem may be in reading and you are not checking the return– EProgrammerNotFound
Hello! I called the Sdk_cis_version method and it prints the SDK version (2014.001.02.1404).
– Thiago Cartoni
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.
– Thiago Cartoni
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.
– Thiago Cartoni
Lerdigital reton 1. (1 = command executed successfully).
– Thiago Cartoni
amostra1.intSize
always returns 0?– EProgrammerNotFound
Yes, @Eprogrammernotfound. intSize always 0 and pDigital always null. =(
– Thiago Cartoni
You have a Delphi version of this system that is working?
– EProgrammerNotFound
I do, @Eprogrammernotfound. With the source and everything.
– Thiago Cartoni
tries to run this in jar in Delphi( programs intended in java and in Delphi flames a jar.
– usersantos
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
– StillBuggin
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?
– Gomiero
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.
– Ruben O. Chiavone
so I know you should call the jar in Delphi, that jar should generate an output for you then just break the string
– usersantos