Java JNA映射来自D2D1的D2D1CreateFactory

时间:2013-03-25 17:54:20

标签: java c++ jna

我试图从DLL D2D1.dll映射函数D2D1CreateFactory。从那里我想建立一个Direct2D Java映射,但那是偏离主题的。到目前为止我有这个:

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

1 个答案:

答案 0 :(得分:2)

根据this referenceD2D1CreateFactory要求指针类型为第三和第四个参数(您只声明三个参数)。

假设你插入了选项指针(一个简单的struct *),你的最后一个参数必须是PointerByReference,因为该函数将“返回”你给它的地址中的指针值。

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

struct *

不要忘记在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()); ctor中致电Structure.read()