Java JNA从D2D1映射D2D1CreateFactory [英] Java JNA mapping D2D1CreateFactory from D2D1

查看:87
本文介绍了Java JNA从D2D1映射D2D1CreateFactory的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图从DLL D2D1.dll映射函数D2D1CreateFactory.从那里开始,我想以创建Direct2D Java映射为基础,但这是不合时宜的.我到目前为止有这个:

I was trying to map the function D2D1CreateFactory from the DLL D2D1.dll. From there I want to build up on creating a Direct2D Java mapping, but that's off-topic. I so far had this:

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

ID2D1Factory看起来像这样:

The ID2D1Factory looks like this:

public class ID2D1Factory extends IUnknown {

    public ID2D1Factory() { }

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

}

当我尝试使用下面的代码运行代码时,将引发"java.lang.Error:无效的内存访问"(打开JNA.setProtected()时).

When I try to run my code using the code below, "java.lang.Error: Invalid memory access" is thrown (when turning on JNA.setProtected()).

要运行的代码:

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

我不知道为什么.我在做错什么吗?

I have no clue why. Is there anything I am doing wrong?

编辑:由于有了技术,我得以获得正确的方法声明.该方法应这样声明:

Thanks to technomage I was able to get the correct method declaration. The method should be declared like this:

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

D2D1_FACTORY_OPTIONS结构的映射如下:

The D2D1_FACTORY_OPTIONS structure was mapped as following:

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();
    }
}

最后,是调用该方法的代码段:

Finally, the snippet to call the method:

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);

推荐答案

根据

According to this reference, D2D1CreateFactory requires pointer types as third and fourth arguments (you are declaring only three arguments).

假设您插入选项指针(简单的struct *),则最后一个参数需要为PointerByReference,因为该函数将在您提供的地址中返回"指针值.

Assuming you insert the options pointer (a simple struct *), your final argument needs to be PointerByReference, since the function will be "returning" a pointer value in the address that you give it.

然后,您可以使用PointerByReference.getValue()初始化新的ID2D1Factory实例(在这种情况下,Structure.ByReference是多余的,因为默认情况下,除非另行明确定义,否则JNA会将所有作为函数参数的结构都视为struct *).

You can then use PointerByReference.getValue() to initialize a new ID2D1Factory instance (the Structure.ByReference in this case is superfluous, since by default all structures as function parameters are treated as struct * by JNA unless explicitly defined otherwise).

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());

也不要忘记在ID2D1Factory(Pointer) ctor中调用Structure.read().

And don't forget to call Structure.read() in your ID2D1Factory(Pointer) ctor.

这篇关于Java JNA从D2D1映射D2D1CreateFactory的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆