Вызов метода Win32 API из Java - PullRequest
34 голосов
/ 05 марта 2010

Мне нужно вызвать некоторые методы в Wininet.dll из Java-программы.

Я могу найти множество учебных пособий о том, как вызывать новую DLL, которую я создаю из Java, но я не могу найти никаких учебных пособий о том, как вызвать уже существующую DLL из Java.

Я знаю, что это касается JNI, но как мне это сделать? Нужно ли мне звонить javah на Wininet.h? Где взять копию Wininet.h? Достаточно указателя на существующее подробное руководство.

Ответы [ 3 ]

42 голосов
/ 05 марта 2010
  1. JNA кажется отраслевым стандартом того, что вы хотите ", обеспечивает программам Java легкий доступ к собственным разделяемым библиотекам (DLL в Windows) без написания чего-либо, кроме кода Java - нет JNI или требуется собственный код "

  2. Существует также Интерфейс внешних функций Java - пример использования
    Если все в порядке, вы можете встроить интерпретатор JRuby и вызвать winapi через jruby-ffi , что намного проще, см. здесь , здесь и здесь

13 голосов
/ 05 марта 2010

Я должен был сделать это некоторое время назад.Вам понадобится компилятор C и файлы заголовков Windows.Я использовал mingw, потому что он бесплатный, и я собирал только один маленький файл.

Сначала вы создаете свой класс.Вот пример:

package org.whatever.thingy;

public class MyClass {
    // Here is a JNI method, identified by 'native'

    public static native callWin32Thingy(int x, int y, boolean z);

    /* At this point, normal class stuff, other methods, variables, whatever */
}

Затем вы используете одну из команд, входящих в JDK, которая автоматически примет ваш класс и сгенерирует файлы .h и .c.Команда "Джава".Сигнатура метода будет выглядеть примерно так:

JNIEXPORT void JNICALL Java_com_whatever_1thingy_MyClass_callWin32Thingy
    (JNIEnv *, jclass, jint, jint, jboolean);

В файле .c вы включаете все необходимые заголовки Windows и уточняете метод.

JNIEXPORT void JNICALL Java_com_whatever_1thingy_MyClass_callWin32Thingy
    (JNIEnv *a, jclass b, jint c, jint d, jboolean e) {
    // Prep steps....

    Win32MethodCallWeCareAbout(x, y, z, hWhatever);

    // Cleanup stuff...
}

Это очень важно вы не переименовываете метод, именно так он ассоциируется с вашим конкретным классом.

Получив это, вы компилируете эти файлы в DLL.Вот команды, которые я использовал для mingw, вам придется настроить классы / пути / и т. Д.

c:/MinGW/bin/gcc -c -Ic:/MinGW/include -I"c:/Program Files/Java/jdk1.5.0_12/include"
    -I"c:/Program Files/Java/jdk1.5.0_12/include/win32" -D__int64="long long"
    com_whatever_thingy_MyClass_JNIHelper.c

c:/MinGW/bin/gcc -shared -o JNIHelper.dll
    com_whatever_thingy_MyClass_JNIHelper_JNIHelper.o
    -Wl,--add-stdcall-alias,--kill-at,--output-def,def_file

Это приведет к созданию некоторых файлов, включая JNIHelper.dll, который я назвал своей DLL.

На данный момент, вы в основном сделали.Вы используете класс Java как обычно, и он будет запускать ваш код Win32 при вызове статического метода.Все, что вам нужно сделать, это импортировать библиотеку.Где-то в вашем коде (я поместил его в статический блок в моем классе) вам понадобится эта строка:

System.loadLibrary("JNIHelper");

Это заставит Java загрузить библиотеку с именем "JNIHelper.dll" и связать ее скод.Это должно быть где-то в пути к библиотеке, о котором знает Java.

Вот и все.Это куча шаблонов, но если вы делаете простую упаковку, это легко.Если вам приходится иметь дело с типами Java или выделением памяти, это ухудшается (примечание: я этого не делал, поэтому у меня нет опыта).

Здесь есть целый учебник здесь (Сначала я нашел сегодня, что выглядел прилично, и вы можете найти других в Интернете. В статье Wikipedia о JNI тоже есть дополнительная информация.

Надеюсь, это поможет.

3 голосов
/ 05 марта 2010

Нельзя напрямую вызывать собственные библиотеки: это потому, что некоторые аргументы в методах не поддерживаются собственным интерфейсом Java.

Существует нечто, называемое GlueGen, это создаст отдельный двоичный файл, который будет динамически связываться с вашей нативной DLL. Сгенерированный двоичный файл совместим с JNI и поэтому может вызываться из Java.

http://en.wikipedia.org/wiki/Gluegen

Чтобы получить заголовочный файл для wininet.dll, вам, вероятно, понадобится Platform SDK (или Windows SDK, новейшая версия). Вы также можете искать в сети онлайн-хранилище, содержащее этот заголовочный файл.

GlueGen потребуется заголовочный файл, компилятор ANSI C и т. Д.

Существует также менее известная библиотека NativeCall, для которой не требуется GlueGen. У него уже есть двоичные файлы, совместимые с Java. Это, очевидно, медленнее, поскольку динамически загружает DLL по запросу из Java. Я еще этим не пользовался, но звучит многообещающе:

http://johannburkard.de/software/nativecall/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...