Как использовать GetProcAddress с JNA? - PullRequest
0 голосов
/ 31 мая 2018

Прежде всего, я новичок JNA.Я хотел бы управлять светодиодным освещением моей материнской платы из кода Java.Для этого Asus предоставляет SDK, который написан на C (C ++?).

Их заголовочный файл выглядит просто:

#pragma once

#include <Windows.h>


typedef void* MbLightControl;
typedef void* GPULightControl;
typedef void* ClaymoreKeyboardLightControl;
typedef void* RogMouseLightControl;


typedef DWORD(WINAPI* EnumerateMbControllerFunc)(MbLightControl handles[], DWORD size);
typedef DWORD(WINAPI* SetMbModeFunc) (MbLightControl handle, DWORD mode);
typedef DWORD(WINAPI* SetMbColorFunc) (MbLightControl handle, BYTE* color, DWORD size);
typedef DWORD(WINAPI* GetMbColorFunc) (MbLightControl handle, BYTE* color, DWORD size);
typedef DWORD(WINAPI* GetMbLedCountFunc)(MbLightControl handle);

typedef DWORD(WINAPI* EnumerateGPUFunc)(GPULightControl handles[], DWORD size);
typedef DWORD(WINAPI* SetGPUModeFunc) (GPULightControl handle, DWORD mode);
typedef DWORD(WINAPI* SetGPUColorFunc) (GPULightControl handle, BYTE* color, DWORD size);
typedef DWORD(WINAPI* GetGPULedCountFunc)(GPULightControl handle);

typedef DWORD(WINAPI* CreateClaymoreKeyboardFunc)(ClaymoreKeyboardLightControl* handle);
typedef DWORD(WINAPI* SetClaymoreKeyboardModeFunc) (ClaymoreKeyboardLightControl handle, DWORD mode);
typedef DWORD(WINAPI* SetClaymoreKeyboardColorFunc) (ClaymoreKeyboardLightControl handle, BYTE* color, DWORD size);
typedef DWORD(WINAPI* GetClaymoreKeyboardLedCountFunc)(ClaymoreKeyboardLightControl handle);

typedef DWORD(WINAPI* CreateRogMouseFunc)(RogMouseLightControl* handle);
typedef DWORD(WINAPI* SetRogMouseModeFunc) (RogMouseLightControl handle, DWORD mode);
typedef DWORD(WINAPI* SetRogMouseColorFunc) (RogMouseLightControl handle, BYTE* color, DWORD size);
typedef DWORD(WINAPI* RogMouseLedCountFunc)(RogMouseLightControl handle);

Я использовал JNAerator для получения сопоставлений JNA, и эторезультат, который я получил:

import com.ochafik.lang.jnaerator.runtime.LibraryExtractor;
import com.ochafik.lang.jnaerator.runtime.MangledFunctionMapper;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.NativeLibrary;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.PointerByReference;
import com.sun.jna.win32.StdCallLibrary.StdCallCallback;

public interface Aura extends Library {

    String JNA_LIBRARY_NAME = LibraryExtractor.getLibraryPath("AURA_SDK", true, Aura.class);

    NativeLibrary JNA_NATIVE_LIB = NativeLibrary.getInstance(Aura.JNA_LIBRARY_NAME, MangledFunctionMapper.DEFAULT_OPTIONS);

    Aura INSTANCE = (Aura) Native.loadLibrary(Aura.JNA_LIBRARY_NAME, Aura.class, MangledFunctionMapper.DEFAULT_OPTIONS);

    interface EnumerateMbControllerFunc extends StdCallCallback {
        int apply(PointerByReference handles, int size);
    }

    interface SetMbModeFunc extends StdCallCallback {
        int apply(Pointer handle, int mode);
    }

    interface SetMbColorFunc extends StdCallCallback {
        int apply(Pointer handle, Pointer color, int size);
    }

    interface GetMbColorFunc extends StdCallCallback {
        int apply(Pointer handle, Pointer color, int size);
    }

    interface GetMbLedCountFunc extends StdCallCallback {
        int apply(Pointer handle);
    }

    interface EnumerateGPUFunc extends StdCallCallback {
        int apply(PointerByReference handles, int size);
    }

    interface SetGPUModeFunc extends StdCallCallback {
        int apply(Pointer handle, int mode);
    }

    interface SetGPUColorFunc extends StdCallCallback {
        int apply(Pointer handle, Pointer color, int size);
    }

    interface GetGPULedCountFunc extends StdCallCallback {
        int apply(Pointer handle);
    }

    interface CreateClaymoreKeyboardFunc extends StdCallCallback {
        int apply(PointerByReference handle);
    }

    interface SetClaymoreKeyboardModeFunc extends StdCallCallback {
        int apply(Pointer handle, int mode);
    }

    interface SetClaymoreKeyboardColorFunc extends StdCallCallback {
        int apply(Pointer handle, Pointer color, int size);
    }

    interface GetClaymoreKeyboardLedCountFunc extends StdCallCallback {
        int apply(Pointer handle);
    }

    interface CreateRogMouseFunc extends StdCallCallback {
        int apply(PointerByReference handle);
    }

    interface SetRogMouseModeFunc extends StdCallCallback {
        int apply(Pointer handle, int mode);
    }

    interface SetRogMouseColorFunc extends StdCallCallback {
        int apply(Pointer handle, Pointer color, int size);
    }

    interface RogMouseLedCountFunc extends StdCallCallback {
        int apply(Pointer handle);
    }
}

В примере кода C ++ они используют GetProcAddress, чтобы получить адрес для вышеуказанных методов, и таким образом они могут их вызывать:

HMODULE hLib = nullptr;

hLib = LoadLibraryA("AURA_SDK.dll");

(FARPROC&)EnumerateMbController = GetProcAddress(hLib, "EnumerateMbController");

DWORD _count = EnumerateMbController(NULL, 0);

Как сделатья делаю то же самое с JNA?

Заранее спасибо.

1 Ответ

0 голосов
/ 31 мая 2018

Я не знаю, почему заголовочные файлы выглядят так, как они выглядят, но на основе предоставленного вами примера C, функция EnumerateMbController , находящаяся в библиотеке AURA_SDK , вызывается с помощьюдва параметра - первый - массив MbLightControl (это непрозрачные указатели), а второй - "размер".

Я бы вывел из контекста:

  • Массив MbLightControl получит указатели
  • size - это размер предоставленного вами массива
  • возвращаемого значенияфункция будет числом действительно возвращенных записей MbLightControl

Вызов с NULL указывает, что он вернет количество возвращенных экземпляров MbLightControl.

Мое предложение для правильной привязки:

public interface Aura extends StdCallLibrary {

    Aura INSTANCE = Native.loadLibrary("AURA_SDK", Aura.class, W32APIOptions.DEFAULT_OPTIONS);

    public static class MbLightControl extends WinDef.PVOID {}

    public int EnumerateMbController(MbLightControl[] handles, int size);
    public int SetMbMode(MbLightControl handle, int mode);
    public int SetMbColor(MbLightControl handle, byte[] color, int size);
    public int GetMbColor(MbLightControl handle, byte[] color, int size);
    public int GetMbLedCount(MbLightControl handle);
}

Это загружает DLL с именем AURA_SDK и делает доступными пять функций.Это также имитирует typedef в заголовочных файлах для MbLightControl . DWORD s связаны как java-интты для упрощения вызова, так как int в java всегда 32-битный, а DWORD в Windows одинаков.

Я не знаю подробностей цветовых кодов, но если это светодиоды RGB, то я предполагаю, что каждый светодиод будет занимать 3 байта в байтовом массиве.

Это может помочьзнаю, что под капотом JNA использовала LoadLibraryEx (старший брат LoadLibrary ), а также GetProcAddress для загрузки функций.

...