Вызов функции C ++ из Java. Сопоставление & quot; const char * & quot;

Я искал это через stackoverflow и в Интернете и еще не нашел ответа.

У меня есть SDK для считывателя отпечатков пальцев, у которого нет исходного кода, то есть я не могу его изменить.

У него есть несколько методов, к которым мне нужно получить доступ, интерфейс которых я перечислю ниже (из RS_API.h):

REALSCANSDK_API int __stdcall RS_InitSDK( const char* configFileName, int option, int* numOfDevice );
REALSCANSDK_API int __stdcall RS_InitDevice( int deviceIndex, int*deviceHandle );
REALSCANSDK_API int __stdcall RS_SetCaptureMode( int deviceHandle, int captureMode, int captureOption, bool withModeLED );
REALSCANSDK_API int __stdcall RS_SetViewWindow( int deviceHandle, HWND windowHandle, RECT drawRectangle, bool autoContrast );
REALSCANSDK_API int __stdcall RS_TakeImageDataEx( int deviceHandle, int timeout, int fingerIndex, bool withLED, unsigned char** imageData, int* imageWidth, int* imageHeight );

Мне удалось преобразовать их все в Delphi, но я также хотел получить доступ к нему из Java-приложения.

Мой прототип таков:

public class Leitor {
public native int  RS_InitSDK(String configFileName, int option, int numOfDevice );

public static void main(String[] args) {
Leitor leitor= new Leitor();
leitor.RS_InitSDK(null, 0, 0);
}
static
{
System.load("C:\\temp\\SDKSuprema\\SDK\\RS_SDK.dll");
}
}

Бит загрузки работает нормально (я полагаю, это означает, что он может найти файл DLL), но когда он запускает собственный метод, он выдает исключение:

Исключение в потоке «main» java.lang.UnsatisfiedLinkError: leitor.Leitor.RS_InitSDK (Ljava / lang / String; II) I
на leitor.Leitor.RS_InitSK (собственный метод)
в leitor.Leitor.main (Leitor.java:14)

Если я переименую dll, это изменит ошибку на «Can’t load library», поэтому я думаю, что проблема заключается в отображении методов.

Я также не смог найти способ сопоставления параметра передачи по ссылке для вызова из Java. Единственное решение состояло в том, чтобы изменить dll, чтобы она возвращала структуру вместо одного результата, но это невозможно, так как я не могу изменить код.

Второй проблемой будет отправка дескриптора окна из SWT в нативный метод JNI …

Любая помощь приветствуется!

2

Решение

Вам нужно написать явный связующий код, который принимает параметры как объекты Java и преобразует их в представление, ожидаемое существующими точками входа C. JVM не сделает это за вас.

Прочитайте Спецификация JNI чтобы научиться писать этот клейкий код.

В частности, чтобы соответствовать вашей декларации Java, точка входа JNI должна иметь имя package_name_here_Leitor_RS_1InitSDK или же package_name_here_Leitor_RS_1InitSDK__Ljava_lang_String_2II; увидеть «Разрешение имен собственных методов» раздел главы 2 спецификации. Эта функция должна принимать некоторые дополнительные аргументы перед видимыми Java; увидеть «Родные методы Аргументы» в спец.

В методе вы получаете строку как jstring значение, которое вы должны использовать GetStringUTFChars вспомогательная функция из JVM для преобразования в строку C.

Для параметров передачи по ссылке вам нужно будет найти способ имитировать их, который имеет смысл для вызывающего кода Java, например, путем передачи объекта, поля которого назначены вашим кодом JNI, или (быстро и быстро) передачи int[] чей первый элемент назначается вашим кодом JNI.

2

Другие решения

Вам необходимо создать склеивающий код c / c ++ для реализации java-методов, вызов javah с классом создаст заголовок, объявляющий нативный аналог java-методов, помеченных как нативные.

Если вы не хотите писать c / c ++, вы можете использовать ЮНА отобразить код Java в существующие методы и структуры c в большинстве случаев.

1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector