[Resolvido!] JNA: chamada de função em DLL

Olá, pessoal! Tudo certo?

Preciso desenvolver uma applet para comunicar com um leitor de impressões digitais (interface USB). O fabricante não fornece
bibliotecas (.jar) para serem utilizadas em projetos Java. O que tenho são DLLs, códigos fonte de aplicações exemplo em VB 6, C#, C++ e VB .NET,
e a documentação que explica o funcionamento das funções das DLLs.
Estou usando JNA para chamar as funções da DLL mas estou com dúvidas. Vejam a seguinte assinatura de uma função da DLL:

UFS_STATUS UFS_API UFS_GetScannerHandle(int nScannerIndex, HUFScanner* phScanner);
Parâmetros:

[code] nScannerIndex [in] Scanner index (0 ~ number of scanners - 1)
phScanner [out] Pointer to handle of the scanner object

HUFScanner defines handle to UFScanner object.
typedef void* HUFScanner;[/code]

Código Java (para teste):

import com.sun.jna.Library;
import com.sun.jna.Native;

public class Teste {

    public interface UFScannerDLL extends Library {   
        public int UFS_GetScannerHandle(int nScannerIndex, ???); // Qual o equivalente em Java?
    }

    public static void main(String[] args) {
        UFScannerDLL  scanner = (UFScannerDLL)Native.loadLibrary("UFScanner", UFScannerDLL.class); 

        scanner.UFS_GetScannerHandle(0, ???);  
    }
}

Minha dúvida é com relação ao parâmetro “HUFScanner* phScanner”. Alguém sabe o equivalente em Java?

Abraços,
Fabio

Visual C++

UFS_STATUS ufs_res;

int nScannerIndex;

HUFScanner hScanner;
 

// Set nScannerIndex to (0 ~ number of scanners - 1 )

// Number of scanner can be retrieved using UFS_GetScannerNumber function

ufs_res = UFS_GetScannerHandle(nScannerIndex, &hScanner);

if (ufs_res == UFS_OK) {

// UFS_GetScannerHandle is succeeded

} else {

// UFS_GetScannerHandle is failed

// Use UFS_GetErrorString function to show error string

}
 

Visual Basic 6.0

Dim ufs_res As UFS_STATUS

Dim nScannerIndex As Long

Dim hScanner As Long

' Set nScannerIndex to (0 ~ number of scanners - 1 )

' Number of scanner can be retrieved using UFS_GetScannerNumber function
 
ufs_res = UFS_GetScannerHandle(nScannerIndex, hScanner)

If (ufs_res = UFS_STATUS.OK) Then
     ' UFS_GetScannerHandle is succeeded
Else
     ' UFS_GetScannerHandle is failed
     ' Use UFS_GetErrorString function to show error string

End If
 

Não existe nem uma arquivo HUFScanner.c perdido por ai?

E outra tenta fazer como o VB, ele é usado como Long…

Eu conheço um pouco JNI e tem os tipos de conversoes, mas JNA nao conheço…

Achei um link interessante sobre o assunto…

http://today.java.net/article/2009/12/20/simplify-native-code-access-jna

Vai na parte que ele diz sobre os typedefs e ponteiros…

Opa, valeu pela resposta KamikazeBr!

Encontrei apenas o arquivo UFScanner.h abaixo:

/////////////////////////////////////////////////////////////////////////////
//
// UniFinger Engine SDK 3.0
//
// UFScanner.h
// Header file for UFScanner module
//
// Copyright (C) 2007 Suprema Inc.
//
/////////////////////////////////////////////////////////////////////////////

#ifndef _UFSCANNER_H_
#define _UFSCANNER_H_

#ifdef UFS_EXPORTS
#define UFS_API __declspec(dllexport) __stdcall
#else
#define UFS_API __stdcall
#endif
#define UFS_CALLBACK __stdcall

#ifdef __cplusplus
extern "C" {
#endif


// Status Definition
#define UFS_STATUS						int

// Status Return Values
#define UFS_OK							0
#define UFS_ERROR						-1
#define UFS_ERR_NO_LICENSE				-101
#define UFS_ERR_LICENSE_NOT_MATCH		-102
#define UFS_ERR_LICENSE_EXPIRED			-103
#define UFS_ERR_NOT_SUPPORTED			-111
#define UFS_ERR_INVALID_PARAMETERS		-112
// For Scanner
#define UFS_ERR_ALREADY_INITIALIZED		-201
#define UFS_ERR_NOT_INITIALIZED			-202
#define UFS_ERR_DEVICE_NUMBER_EXCEED	-203
#define UFS_ERR_LOAD_SCANNER_LIBRARY	-204
#define UFS_ERR_CAPTURE_RUNNING			-211
#define UFS_ERR_CAPTURE_FAILED			-212
// For Extraction
#define UFS_ERR_NOT_GOOD_IMAGE			-301
#define UFS_ERR_EXTRACTION_FAILED		-302
// For Extraction: Core Detection
#define UFS_ERR_CORE_NOT_DETECTED		-351
#define UFS_ERR_CORE_TO_LEFT			-352
#define UFS_ERR_CORE_TO_LEFT_TOP		-353
#define UFS_ERR_CORE_TO_TOP				-354
#define UFS_ERR_CORE_TO_RIGHT_TOP		-355
#define UFS_ERR_CORE_TO_RIGHT			-356
#define UFS_ERR_CORE_TO_RIGHT_BOTTOM	-357
#define UFS_ERR_CORE_TO_BOTTOM			-358
#define UFS_ERR_CORE_TO_LEFT_BOTTOM		-359

// Parameters
// For Scanner
#define UFS_PARAM_TIMEOUT				201
#define UFS_PARAM_BRIGHTNESS			202
#define UFS_PARAM_SENSITIVITY			203
#define UFS_PARAM_SERIAL				204
// For Extraction
#define UFS_PARAM_DETECT_CORE			301
#define UFS_PARAM_TEMPLATE_SIZE			302
#define UFS_PARAM_USE_SIF				311

// Scanner Type
#define UFS_SCANNER_TYPE_SFR200			1001
#define UFS_SCANNER_TYPE_SFR300			1002
#define UFS_SCANNER_TYPE_SFR300v2		1003


/////////////////////////////////////////////////////
// Template Type & finger position 
// & impression type & quality value  added by k.k.y 2008.08 
/////////////////////////////////////////////////////
#define UFS_TEMPLATE_TYPE_SUPREMA               2001
#define UFS_TEMPLATE_TYPE_ISO19794_2            2002
#define UFS_TEMPLATE_TYPE_ANSI378               2003
/////////////////////////////////////////////////////

typedef void* HUFScanner;

typedef int UFS_CALLBACK UFS_SCANNER_PROC(const char* szScannerID, int bSensorOn, void* pParam);
typedef int UFS_CALLBACK UFS_CAPTURE_PROC(HUFScanner hScanner, int bFingerOn, unsigned char* pImage, int nWidth, int nHeight, int nResolution, void* pParam);


UFS_STATUS UFS_API UFS_Init();
UFS_STATUS UFS_API UFS_Update();
UFS_STATUS UFS_API UFS_Uninit();

UFS_STATUS UFS_API UFS_SetScannerCallback(UFS_SCANNER_PROC* pScannerProc, void* pParam);
UFS_STATUS UFS_API UFS_RemoveScannerCallback();

UFS_STATUS UFS_API UFS_GetScannerNumber(int* pnScannerNumber);
UFS_STATUS UFS_API UFS_GetScannerHandle(int nScannerIndex, HUFScanner* phScanner);
UFS_STATUS UFS_API UFS_GetScannerHandleByID(const char* szScannerID, HUFScanner* phScanner);
UFS_STATUS UFS_API UFS_GetScannerIndex(HUFScanner hScanner, int* pnScannerIndex);
UFS_STATUS UFS_API UFS_GetScannerID(HUFScanner hScanner, char* szScannerID);
UFS_STATUS UFS_API UFS_GetScannerType(HUFScanner hScanner, int* pnScannerType);

UFS_STATUS UFS_API UFS_GetParameter(HUFScanner hScanner, int nParam, void* pValue);
UFS_STATUS UFS_API UFS_SetParameter(HUFScanner hScanner, int nParam, void* pValue);

UFS_STATUS UFS_API UFS_IsSensorOn(HUFScanner hScanner, int* pbSensorOn);
UFS_STATUS UFS_API UFS_IsFingerOn(HUFScanner hScanner, int* pbFingerOn);

UFS_STATUS UFS_API UFS_CaptureSingleImage(HUFScanner hScanner);
UFS_STATUS UFS_API UFS_StartCapturing(HUFScanner hScanner, UFS_CAPTURE_PROC* pCaptureProc, void* pParam);
UFS_STATUS UFS_API UFS_IsCapturing(HUFScanner hScanner, int* pbCapturing);
UFS_STATUS UFS_API UFS_AbortCapturing(HUFScanner hScanner);

UFS_STATUS UFS_API UFS_Extract(HUFScanner hScanner, unsigned char* pTemplate, int* pnTemplateSize, int* pnEnrollQuality);

UFS_STATUS UFS_API UFS_SetEncryptionKey(HUFScanner hScanner, unsigned char* pKey);
UFS_STATUS UFS_API UFS_EncryptTemplate(HUFScanner hScanner, unsigned char* pTemplateInput, int nTemplateInputSize, unsigned char* pTemplateOutput, int* pnTemplateOutputSize);
UFS_STATUS UFS_API UFS_DecryptTemplate(HUFScanner hScanner, unsigned char* pTemplateInput, int nTemplateInputSize, unsigned char* pTemplateOutput, int* pnTemplateOutputSize);

UFS_STATUS UFS_API UFS_GetCaptureImageBufferInfo(HUFScanner hScanner, int* pnWidth, int* pnHeight, int* pnResolution);
UFS_STATUS UFS_API UFS_GetCaptureImageBuffer(HUFScanner hScanner, unsigned char* pImageData);
UFS_STATUS UFS_API UFS_DrawCaptureImageBuffer(HUFScanner hScanner, HDC hDC, int nLeft, int nTop, int nRight, int nBottom, int bCore);
UFS_STATUS UFS_API UFS_SaveCaptureImageBufferToBMP(HUFScanner hScanner, char* szFileName);
UFS_STATUS UFS_API UFS_ClearCaptureImageBuffer(HUFScanner hScanner);

UFS_STATUS UFS_API UFS_GetErrorString(UFS_STATUS res, char* szErrorString);

UFS_STATUS UFS_API UFS_SetTemplateType(HUFScanner hScanner, int nTemplateType);
UFS_STATUS UFS_API UFS_GetTemplateType(HUFScanner hScanner, int *nTemplateType);

#ifdef __cplusplus
}
#endif

#endif // _UFSCANNER_H_

Tentativa com long

[code]public interface UFScannerDLL extends Library {
public int UFS_GetScannerHandle(int nScannerIndex, long param);
}

public static void main(String[] args) {
UFScannerDLL scanner = (UFScannerDLL)Native.loadLibrary(“UFScanner”, UFScannerDLL.class);
scanner.UFS_GetScannerHandle(0, 1L);
}
[/code]

Erro:

[code]#

An unexpected error has been detected by Java Runtime Environment:

EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0b136b8a, pid=2520, tid=768

Java VM: Java HotSpot™ Client VM (1.6.0-b105 mixed mode)

Problematic frame:

C [UFScanner.dll+0x6b8a]

An error report file with more information is saved as hs_err_pid2520.log

If you would like to submit a bug report, please visit:

http://java.sun.com/webapps/bugreport/crash.jsp

[/code]

Tentativa com long[]

[code]public interface UFScannerDLL extends Library {
public int UFS_GetScannerHandle(int nScannerIndex, long[] phScanner);
}

public static void main(String[] args) {
UFScannerDLL scanner = (UFScannerDLL)Native.loadLibrary(“UFScanner”, UFScannerDLL.class);
long[] param = new long[1];
param[0] = 1L;
int codRetorno =scanner.UFS_GetScannerHandle(0, param);
System.out.println("Cód. Retorno Scanner Handle: " + codRetorno);
}
[/code]

Com long[] não dá Exception porém, o código retornado pela função é -112.

Cód. Retorno Scanner Handle: -112

De acordo com a documentação:

UFS_ERR_INVALID_PARAMETERS -112 Input parameters are invalid

Também tentei com com.sun.jna.NativeLong e com.sun.jna.NativeLong[] sem sucesso.

Opa, funcionou com NativeLong[]. Agora, o problema está na chamada da função que faz a leitura da impressão digital.

UFS_STATUS UFS_API UFS_CaptureSingleImage(HUFScanner hScanner);

Java

[code]
public interface UFScannerDLL extends Library {
public int UFS_CaptureSingleImage(NativeLong[] scanner);
}

public static void main(String[] args) {
NativeLong[] phScanner = new NativeLong[1];
phScanner[0] = new NativeLong(1);
codRetorno = scanner.UFS_CaptureSingleImage(phScanner);
}[/code]

Erro

#
# An unexpected error has been detected by Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x7c910ed2, pid=4884, tid=2620
#
# Java VM: Java HotSpot(TM) Client VM (1.6.0-b105 mixed mode)
# Problematic frame:
# C  [ntdll.dll+0x10ed2]
#
# An error report file with more information is saved as hs_err_pid4884.log
#
# If you would like to submit a bug report, please visit:
#   http://java.sun.com/webapps/bugreport/crash.jsp
#

[error occurred during error reporting, step 270, id 0xc0000005]

Também tentei com long. Não dá Exception mas retorna o código -112…

Que estranho, os tópicos sumiram da 1ª página

[quote=fabio_yamauti]Opa, funcionou com NativeLong[]. Agora, o problema está na chamada da função que faz a leitura da impressão digital.

UFS_STATUS UFS_API UFS_CaptureSingleImage(HUFScanner hScanner);

[/quote]

Verifique na documentação do JNA o mapeamento de tipos C/C++ para java.
https://jna.dev.java.net/

Observe que HUFScanner é um ponteiro, então você tem um tipo especifico (Pointer) Java para este tipo.

typedef void* HUFScanner

Existem alguns tipos mapeados para tipos definidos na WIN32 API.
Como:
W32API.HANDLE
W32API.HDC
W32API.HANDLEByReference
W32API.LONG_PTR
Etc…

Depois que você entender como mapear os tipos corretamente JNA é show!

Parece estar no caminho certo, mas se preste atenção ao um detalhe a Exception que ocorre diz que seu parametro de entrada está incorreto, mas nao pelo seu tipo e sim pelo seu valor…logo…

Use sempre long[] só que ao invés de passar 1 como no primeira chamada olha a documentação…

Pessoal, muito obrigado pela ajuda! Consegui fazer funcionar utilizando os tipos fornecidos pelo JNA! :smiley:

Abaixo as assinaturas das funções da DLL e em seguida como ficou em Java.

typedef void* HUFScanner;

UFS_STATUS UFS_API UFS_Init();
UFS_STATUS UFS_API UFS_GetScannerNumber(int* pnScannerNumber);
UFS_STATUS UFS_API UFS_GetScannerHandle(int nScannerIndex, HUFScanner* phScanner);
UFS_STATUS UFS_API UFS_SetParameter(HUFScanner hScanner, int nParam, void* pValue);
UFS_STATUS UFS_API UFS_ClearCaptureImageBuffer(HUFScanner hScanner);
UFS_STATUS UFS_API UFS_CaptureSingleImage(HUFScanner hScanner);
UFS_STATUS UFS_API UFS_Extract(HUFScanner hScanner, unsigned char* pTemplate, int* pnTemplateSize, int* pnEnrollQuality);
UFS_STATUS UFS_API UFS_SaveCaptureImageBufferToBMP(HUFScanner hScanner, char* szFileName);

Java

public interface UFScannerDLL extends Library { public int UFS_Init(); public int UFS_GetScannerNumber(IntByReference pnScannerNumber); public int UFS_GetScannerHandle(int nScannerIndex, LongByReference phScanner); public int UFS_SetParameter(NativeLong hScanner, int nParam, LongByReference pValue); public int UFS_SetParameter(NativeLong hScanner, int nParam, IntByReference pValue); public int UFS_ClearCaptureImageBuffer(NativeLong hScanner); public int UFS_CaptureSingleImage(NativeLong hScanner); public int UFS_Extract(NativeLong scanner, byte[] pTemplate, IntByReference pnTemplateSize, IntByReference pnEnrollQuality); public int UFS_SaveCaptureImageBufferToBMP(NativeLong hScanner, String szFileName); }