是否可以使用JNA/JNI访问本机COM/DirectX API方法? [英] Is it possible to use JNA/JNI to access native COM/DirectX API methods?

查看:124
本文介绍了是否可以使用JNA/JNI访问本机COM/DirectX API方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用JNA调用此本机Windows方法:

I'm trying to call this native Windows method using JNA:

HRESULT WINAPI DirectSoundCreate(LPGUID lpGuid, LPDIRECTSOUND* ppDS, LPUNKNOWN pUnkOuter );

但是我真的很难理解在Java方面应该使用什么作为参数.使用JNA,您应该创建与本机C结构匹配的Java类,而我已经成功地使用WinAPI的其他部分.

But I'm really struggling with understanding what I should use as parameters on the Java side of things. With JNA you're supposed to create Java classes matching the native C structs, and I have done so succesfully with other parts of the WinAPI.

据我到目前为止(我认为)的理解,LPDIRECTSOUND是指向DirectSound结构的长指针"的typedef,而LPUNKNOWN是指向未知的长指针"的typedef?

From what I've (I think) understood so far the LPDIRECTSOUND is a typedef to a "Long pointer to a DirectSound struct" and LPUNKNOWN is a typedef "Long pointer to an Unknown"?

我在DSound.h中找到了本机结构IDirectSound和IUnknown.我应该使用这些吗?但是,我找不到有关这些结构包含的规范,因此,当我尝试将它们镜像为在Java端扩展Structure的空类时,我会得到

I've found the native structs IDirectSound and IUnknown in DSound.h. Am I supposed to use these? I can't find a specification on what these structs contain, however, so when I try to mirror them as empty classes extending Structure on the Java side I get

IllegalArgumentException:结构类se.abjorklund.win32.jna.dsound.IDirectSound的大小未知或为零(确保所有字段都是公共的)

IllegalArgumentException: Structure class se.abjorklund.win32.jna.dsound.IDirectSound has unknown or zero size (ensure all fields are public)

因此,这显然行不通.我猜想我在这里缺少一些基本知识,也许与我不理解的COM/Direct API有关,只要我能得到如下的指针,读起来"之类的答案就很酷阅读什么!

So that obviously doesn't work. I'm guessing I'm missing something fundamental here, maybe it has something to do with the COM/Direct API that I don't understand, and answers like "go read up" are cool, as long as I can get pointers as to what to read!

下面是我要使用JNA移植到Java的C程序的工作片段.

Below is a working snippet of the C program I'm trying to port to Java using JNA.

LPDIRECTSOUND directSound; if (directSoundCreate && SUCCEEDED(directSoundCreate(0, &directSound, 0)))

LPDIRECTSOUND directSound; if (directSoundCreate && SUCCEEDED(directSoundCreate(0, &directSound, 0)))

因此在C语言中,您只需将指针传递给LPDIRECTSOUND.我想我需要制作一个LPDIRECTSOUND类来扩展Java中的JNA Structure类吗?我在这里接近答案还是遥遥无期?

So in C you just pass a pointer to a LPDIRECTSOUND. I guess I need to make a LPDIRECTSOUND class extending the JNA Structure class in Java? Am I close to the answer here or way off?

推荐答案

JNA确实支持COM,并且

JNA does support COM and there are several mappings already present in the com.sun.jna.platform.win32.COM package, including the IUnknown interface and the corresponding Unknown class implementing it.

您可以实现IDirectSound接口(可选),也可以通过扩展Unknown直接实现类.您将必须使用

You could implement an IDirectSound interface (optional) or just directly implement the class by extending Unknown. You will have to map the functions you need using _invokeNativeObject() (or the -Int and -Void variants).

我在

I contributed several COM classes needed to query WMI in the WbemCli.java class that can serve as examples of how to pass those parameters. (Note: I probably shouldn't have used the I interface prefix on the concrete classes, but it's too late now.)

函数参数是vtableId,用于参数的对象数组和用于返回类型的类.要获取vtableId,您必须在头文件的directSoundVtbl结构中计算方法(索引为0).我没有权威性Dsound.h文件的副本,但这里是(a)(例如,CreateSoundBuffer的ID为3).从Unknown继承已经为您提供了Vtbl中的前3个功能(id的0、1和2).

Function parameters are the vtableId, an array of objects for the arguments, and a class for the return type. To get the vtableId, you'll have to count the methods (0-indexed) in the directSoundVtbl struct in the header file. I don't have a copy of the authoritative Dsound.h file, but here's one possibility for that ordering (e.g., CreateSoundBuffer would have id 3). Inheriting from Unknown already gets you the first 3 functions in the Vtbl (id's 0, 1, and 2).

这是一个(完全未经测试的)示例,可以帮助您入门.

Here's a (completely untested) example to get you started.

public interface DSound {

    @FieldOrder ({ "dwSize", "dwFlags", ... })
    class DSBUFFERDESC extends Structure {
        public int dwSize;
        public int dwFlags;
        // continue conventional JNA Structure mapping here
        // may have to map nested structures
    }

    class DirectSoundBuffer extends Unknown {
        // methods invoking COM similar to below
    }

    class DirectSound extends Unknown {
        public DirectSound() {
        }

        public DirectSound(Pointer p) {
            super(p);
        }

        public HRESULT CreateSoundBuffer(DSBUFFERDESC lpcDSBufferDesc, DirectSoundBuffer lplpDirectSoundBuffer, Unknown pUnkOuter) {
            // CreateSoundBuffer is 4th method of directSoundVtbl in Dsound.h
            return (HRESULT) _invokeNativeObject(3,
                    new Object[] { getPointer(), lpcDSBufferDesc, lplpDirectSoundBuffer, pUnkOuter }, HRESULT.class);
        }

        // Map whatever functions you need, or all of them!
    }
}

这篇关于是否可以使用JNA/JNI访问本机COM/DirectX API方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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