You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用JNA调用IMMDeviceEnumerator返回S_FALSE及空指针引发异常

使用JNA调用Windows API获取音频端点时遇到S_FALSE和空指针问题

我正在用JNA结合Windows API开发,目标是调用MMDeviceEnumerator实例的GetDefaultAudioEndpoint方法获取MMDevice接口实例,但调用后返回HRESULT值为S_FALSE(1),得到的指针为空(null@0x2bd70eebeb0),后续基于该空指针调用IAudioEndpointVolume的Activate方法时触发NullPointerException。

运行时错误日志

Calling MMDeviceEnumerator.create()
response: 0
Got MMDeviceEnumerator
Pointer: native@0x2bd70f68590
Pointer.getPointer(): native@0x2bd70f68590

Calling mmEnumerator.GetDefaultAudioEndpoint(args)
response: 1
Got mmDevice
Pointer: null@0x2bd70eebeb0
Pointer.getValue(): null
Pointer.getPointer(): allocated@0x2bd70eebeb0 (8 bytes)
null

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "com.sun.jna.Pointer.getPointer(long)" because "vptr" is null
        at com.sun.jna.platform.win32.COM.COMInvoker._invokeNativeObject(COMInvoker.java:46)
        at spicey.IAudioEndpointVolume.Activate(App.java:76)
        at spicey.App.main(App.java:58)

完整程序代码

public final class App extends Unknown {

    public static final CLSID CLSID_IMMDeviceEnumerator = new CLSID("bcde0395-e52f-467c-8e3d-c4579291692e");
    public static final GUID IID_IMMDeviceEnumerator = new GUID("a95664d2-9614-4f35-a746-de8db63617e6");
    public static final GUID IID_IAudioEndpointVolume = new GUID("5CDF2C82-841E-4546-9722-0CF74078229A");
    public static final GUID IID_IAudioStreamVolume = new GUID("93014887-242D-4068-8A15-CF5E93B90FE3");

    public static void main(String[] args) {
        Ole32.INSTANCE.CoInitializeEx(null, 0); // 0 is multi threaded
        System.out.println("Calling MMDeviceEnumerator.create()");
        MMDeviceEnumerator mmEnumerator = MMDeviceEnumerator.create();
        System.out.println("Got MMDeviceEnumerator");
        System.out.println("Pointer: " + mmEnumerator.getPointer());
        System.out.println("Pointer.getPointer(): " + mmEnumerator.getPointer());
        System.out.println();

        PointerByReference ppEndpoint = new PointerByReference();
        System.out.println("Calling mmEnumerator.GetDefaultAudioEndpoint(args)");
        mmEnumerator.GetDefaultAudioEndpoint(0, 0, ppEndpoint);

        System.out.println("Got mmDevice");
        System.out.println("Pointer: " + ppEndpoint);
        System.out.println("Pointer.getValue(): " + ppEndpoint.getValue());
        System.out.println("Pointer.getPointer(): " + ppEndpoint.getPointer());
        System.out.println();

        IAudioEndpointVolume iEndpoint = IAudioEndpointVolume.create(ppEndpoint.getPointer());
        PointerByReference ppInterface = new PointerByReference();
        iEndpoint.Activate(IID_IAudioEndpointVolume, WTypes.CLSCTX_ALL, ppInterface.getPointer());

    }

}

class IAudioEndpointVolume extends Unknown {

    public IAudioEndpointVolume(Pointer p) {
        super(p);

    }

    public static IAudioEndpointVolume create(Pointer p) {
        return new IAudioEndpointVolume(p);
    }

    public void Activate(GUID iid, int dwClsCtx, Pointer ppInterface) {
        HRESULT res = (HRESULT) _invokeNativeObject(1, new Object[] { getPointer(), iid, dwClsCtx, null, ppInterface },
                HRESULT.class);
        COMUtils.checkRC(res);

    }

}

class MMDeviceEnumerator extends Unknown {
    public static final CLSID CLSID_MMDeviceEnumerator = new CLSID("bcde0395-e52f-467c-8e3d-c4579291692e");
    public static final GUID IID_IMMDeviceEnumerator = new GUID("a95664d2-9614-4f35-a746-de8db63617e6");

    public static interface Ole32 extends Library {
        Ole32 INSTANCE = (Ole32) Native.load("Ole32",
                Ole32.class);

        HRESULT CoCreateInstance(GUID rclsid, Pointer pUnkOuter, int dwClsContext, GUID riid, PointerByReference ppv);

    }

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

    public static MMDeviceEnumerator create() {
        PointerByReference pEnumerator = new PointerByReference();

        HRESULT hres = Ole32.INSTANCE.CoCreateInstance(
                CLSID_MMDeviceEnumerator, null,
                WTypes.CLSCTX_ALL, IID_IMMDeviceEnumerator,
                pEnumerator);
        System.out.println("response: " + hres);
        if (COMUtils.FAILED(hres)) {
            return null;
        }

        return new MMDeviceEnumerator(pEnumerator.getValue());
    }

    // functionz
    public void GetDefaultAudioEndpoint(int dataFlow, int role, PointerByReference ppEndpoint) {
        HRESULT res = (HRESULT) _invokeNativeObject(2,
                new Object[] { getPointer(), dataFlow, role, ppEndpoint }, HRESULT.class);

        COMUtils.checkRC(res);
        System.out.println("response: " + res);

    }
}

COMInvoker类代码

public abstract class COMInvoker extends PointerType {

    protected int _invokeNativeInt(int vtableId, Object[] args) {
        Pointer vptr = this.getPointer().getPointer(0);
        // we take the vtable id and multiply with the pointer size (4 bytes on
        // 32bit OS)
        Function func = Function.getFunction(vptr.getPointer(vtableId
                * Native.POINTER_SIZE));
        return func.invokeInt(args);
    }

    protected Object _invokeNativeObject(int vtableId, Object[] args, Class<?> returnType) {
        Pointer vptr = this.getPointer().getPointer(0);
        // we take the vtable id and multiply with the pointer size (4 bytes on
        // 32bit OS)
        Function func = Function.getFunction(vptr.getPointer(vtableId
                * Native.POINTER_SIZE));
        return func.invoke(returnType, args);
    }

    protected void _invokeNativeVoid(int vtableId, Object[] args) {
        Pointer vptr = this.getPointer().getPointer(0);
        // we take the vtable id and multiply with the pointer size (4 bytes on
        // 32bit OS)
        Function func = Function.getFunction(vptr.getPointer(vtableId
                * Native.POINTER_SIZE));
        func.invokeVoid(args);
    }

}

已经检查过COMInvoker类但未找到问题所在,恳请提供解决方案。


内容的提问来源于stack exchange,提问作者Spicey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 19:45:55