Java JNA mapping D2D1CreateFactory из D2D1

Я пытался сопоставить функцию D2D1CreateFactory из DLL D2D1.dll. Оттуда я хочу продолжить создание Java-карт Direct2D, но это не по теме. У меня до сих пор было это:

public WinNT.HRESULT D2D1CreateFactory(int factoryType, REFIID riid, ID2D1Factory.ByReference ppIFactory);

ID2D1Factory выглядит так:

public class ID2D1Factory extends IUnknown {

public ID2D1Factory() { }

public ID2D1Factory(Pointer pvInstance) {
super(pvInstance);
}

}

Когда я пытаюсь запустить свой код, используя приведенный ниже код, выдается «java.lang.Error: Invalid access access» (при включении JNA.setProtected ()).

Код для запуска:

ID2D1Factory.ByReference ref= new ID2D1Factory.ByReference();
D2D1.INSTANCE.D2D1CreateFactory(0, new REFIID(new IID("06152247-6f50-465a-9245-118bfd3b6007").toByteArray()), ref);

Понятия не имею почему. Что-то я делаю не так?

РЕДАКТИРОВАТЬ: Благодаря technomage я смог получить правильное объявление метода. Метод должен быть объявлен так:

public WinNT.HRESULT D2D1CreateFactory(int factoryType, REFIID riid, D2D1_FACTORY_OPTIONS opts, PointerByReference pref);

Структура D2D1_FACTORY_OPTIONS была отображена следующим образом:

public static class D2D1_FACTORY_OPTIONS extends Structure {
public int debugLevel;
protected List<String> getFieldOrder() {
return Arrays.asList(new String[] { "debugLevel" });
}
public D2D1_FACTORY_OPTIONS() {}
public D2D1_FACTORY_OPTIONS(int size) {
super(new Memory(size));
}
public D2D1_FACTORY_OPTIONS(Pointer memory) {
super(memory);
read();
}
}

Наконец, фрагмент для вызова метода:

D2D1_FACTORY_OPTIONS opts = new D2D1_FACTORY_OPTIONS();
PointerByReference pp = new PointerByReference();
D2D1.INSTANCE.D2D1CreateFactory(0, new REFIID(new IID("06152247-6f50-465a-9245-118bfd3b6007").toByteArray()), opts, pp);

0

Решение

В соответствии с эта ссылка, D2D1CreateFactory требует указателя типов в качестве третьего и четвертого аргументов (вы объявляете только три аргумента).

Предполагая, что вы вставляете указатель параметров (простой struct *), ваш последний аргумент должен быть PointerByReference, поскольку функция будет «возвращать» значение указателя в адресе, который вы ему дадите.

Вы можете использовать PointerByReference.getValue() инициализировать новый ID2D1Factory экземпляр ( Structure.ByReference в этом случае является излишним, так как по умолчанию все структуры как параметры функции рассматриваются как struct * JNA, если не указано иное).

public WinNT.HRESULT D2D1CreateFactory(int factoryType, REFIID riid, D2D1_FACTORY_OPTIONS options, ID2D1Factory ppIFactory);

public class D2D1_FACTORY_OPTIONS extends Structure { ... }

D2D1_FACTORY_OPTIONS options = ...;
PointerByReference pref = new PointerByReference();

D2D1.INSTANCE.D2D1CreateFactory(0, new REFIID(...), options, pref);
ID2D1Factory factory = new ID2D1Factory(pref.getValue());

И не забудьте позвонить Structure.read() в вашем ID2D1Factory(Pointer) т е р.

2

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

Других решений пока нет …

По вопросам рекламы [email protected]