Is it possible to use JNA/JNI to access native COM/DirectX API methods?

女生的网名这么多〃 提交于 2021-02-08 07:38:33

问题


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

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

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.

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"?

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: Structure class se.abjorklund.win32.jna.dsound.IDirectSound has unknown or zero size (ensure all fields are public)

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!

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

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?


回答1:


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.

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

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!
    }
}


来源:https://stackoverflow.com/questions/61814337/is-it-possible-to-use-jna-jni-to-access-native-com-directx-api-methods

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!