Вызов методов из очень сложной C32 Win32 DLL с множеством классов Java процессом через JNA - PullRequest
0 голосов
/ 20 марта 2020

У меня есть очень сложная и большая DLL, написанная на C ++ для Win32 разработчиками из других отделов, которая должна использоваться моими java -процессами. Что у меня есть:

Ограничения: Мне не разрешено (хотя у меня есть файл .sol) вносить какие-либо изменения в эту DLL.

Цель : Я хочу, чтобы мои java -процессы могли вызывать некоторые методы из этой DLL.

Инструменты: Сначала я хочу попробовать это с JNA (второй JNI) .

Проблема:

Я прочитал некоторую общую информацию о JNA и понял, что сначала вы создаете прототипы методов, которые вы хотите вызвать в интерфейсе. Хорошо, теперь вопрос в следующем: методы, которые я хочу вызвать, принимают в качестве параметров самоопределяемые объекты из проекта DLL. Например, у меня есть функция в DLL, например:

__declspec(dllexport) BOOL WINAPI NiceFunction( 
          Dummy_State *ModuleState, Dummy_Handle Handle, Dummy_Exception &Exception,
          LPCTSTR name, DWORD timer);

Где все Dummy_ объекты имеют классы, определенные в этой DLL.

Вопрос 1: как вызвать с помощью JNA такие функции в моем java процессе?

Вопрос 2: можно ли использовать эти объекты как-то прямые в моем java процессе? Может быть, импортировать как-то конструктор? Однако конструкторы этих объектов часто требуют вызова конструкторов родительского (ых) класса (ов).

Вопрос 3: И последнее, но не менее важное: моя DLL также вызвала две дополнительные DLL и широко использовала данные из них (некоторые из Dummy_ объектов). Нужно ли мне импортировать (как-то) их в моем java процессе через JNA или нет?

1 Ответ

1 голос
/ 22 марта 2020

JNA работает только с C функциями, но не с C ++. Единственные функции C ++, которые вы сможете отобразить, должны быть выведены с помощью extern "C". Если это не так, и вы не можете изменить DLL, вам, возможно, придется написать свою собственную оболочку DLL, которая имеет extern "C" версии.

Как вызвать с помощью JNA такие функции:

Вы должны сопоставить их с Java интерфейсом. Например:

public interface ComplicatedAndBigLibrary {
    // Create an instance to access the mapped functions with
    // the String in quotes is the filename, minus .dll
    ComplicatedAndBigLibrary INSTANCE = 
        (ComplicatedAndBigLibrary) Native.load("compbiglib", W32APIOptions.DEFAULT_OPTIONS);

    // Map the C structures or typedefs
    // Use "extends" as needed for parents
    @FieldOrder({"field1", "field2"})
    class Dummy_State extends Structure {
        // map structure fields here
        public int field1;
        public byte field2;
    }

    class Dummy_Handle extends WinNT.HANDLE {
        // any overrides you need
    }

    // Map your functions (that were externalized)
    boolean NiceFunction( 
          Dummy_State ModuleState, Dummy_Handle Handle, Dummy_Exception ExceptionPointer,
          LPCTSTR name, DWORD timer);
}

Посмотрите на исходный код JNA в пакете com.sun.jna.platform.win32 для многих типов примеров, основанных на Windows DLL. По сути, вы делаете то же самое для своей DLL.

Используйте эти объекты как-то прямо в моем java процессе

ComplicatedAndBigLibrary CABL = ComplicatedAndBigLibrary.INSTANCE;
CABL.NiceFunction(foo, bar, ...)

Также называется двумя дополнительные библиотеки DLL и широко используемые данные из них

Вам необходимо сопоставить другие библиотеки DLL аналогичным образом (создайте интерфейс, используйте Native.load() и сопоставьте функции / константы / et c.)

...