如何使用更具体的结构类型代替更通用的结构类型?

时间:2015-09-28 08:56:37

标签: java c++ struct declaration jna

我正在使用一个可以使用java的Windows设备管理器。 我坚持尝试传递没有错误SetupDiSetClassInstallParams函数。 (我正在尝试禁用设备。)

我在C ++中运行完全相同的结构(必要的方式),我没有任何问题。

我收到ERROR_INVALID_USER_BUFFER错误。当我尝试在C ++中获取此错误时,我需要更改错误的SP_PROPCHANGE_PARAMS结构值。

我的结构解决方案:

    public static class SP_CLASSINSTALL_HEADER extends Structure {

    public static class ByReference extends SP_CLASSINSTALL_HEADER implements Structure.ByReference {
        public ByReference() {
        }

        public ByReference(Pointer memory) {
            super(memory);
        }
    }

    public SP_CLASSINSTALL_HEADER() {
        cbSize = size();
    }

    public SP_CLASSINSTALL_HEADER(Pointer memory) {
        super(memory);
        read();
    }

    public int cbSize;
    public long InstallFunction; **/* <-- this should be int or else buffer size changes, dll cannot place variables on right places. */**

    protected List getFieldOrder() {
        return Arrays.asList(new String[] { "cbSize", "InstallFunction" });
    }
}

public static class SP_PROPCHANGE_PARAMS extends Structure {

    public static class ByReference extends SP_PROPCHANGE_PARAMS implements Structure.ByReference {
        public ByReference() {
        }

        public ByReference(Pointer memory) {
            super(memory);
        }
    }

    public SP_PROPCHANGE_PARAMS() {
    }

    public SP_PROPCHANGE_PARAMS(Pointer memory) {
        super(memory);
        read();
    }

    public SP_CLASSINSTALL_HEADER ClassInstallHeader = new SP_CLASSINSTALL_HEADER();
    public int StateChange;
    public int Scope;
    public int HwProfile;

    protected List getFieldOrder() {
        return Arrays.asList(new String[] { "ClassInstallHeader", "StateChange", "Scope", "HwProfile" });
    }
}

我的功能减少:

boolean SetupDiSetClassInstallParams(WinNT.HANDLE hDevInfo, Pointer deviceInfoData, Pointer classInstallHeader, int size);

如何调用此功能:

    SP_PROPCHANGE_PARAMS spPropChangeParams = new SP_PROPCHANGE_PARAMS(); 
    spPropChangeParams.ClassInstallHeader.InstallFunction = DISetupApi.DIF_PROPERTYCHANGE;
    spPropChangeParams.Scope = DISetupApi.DICS_FLAG_GLOBAL;
    spPropChangeParams.HwProfile = 0;
    spPropChangeParams.StateChange = DISetupApi.DICS_DISABLE;
    int spPropChangeParamsSize = spPropChangeParams.size();
    SP_CLASSINSTALL_HEADER classInstallHeaderReference = new SP_CLASSINSTALL_HEADER(spPropChangeParams.getPointer());

    setupApi.SetupDiSetClassInstallParams(hDevInfo, device.getSPDeviceInfoData().getPointer(), classInstallHeaderReference.getPointer(),
            spPropChangeParamsSize);

它如何在c ++中运行:

SP_PROPCHANGE_PARAMS spPropChangeParams;    
spPropChangeParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
spPropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
spPropChangeParams.Scope = DICS_FLAG_GLOBAL;
spPropChangeParams.HwProfile = 0; 
spPropChangeParams.StateChange = DICS_DISABLE;

SetupDiSetClassInstallParams(hDeviceInfo, &device.getDeviceInfoData(), (SP_CLASSINSTALL_HEADER*)&spPropChangeParams, sizeof(spPropChangeParams));

实际上我混合并匹配了这些结构和函数的太多方法我最后更改了变量类型的结构和参数类型的函数,除了错误之外我什么都得不到。我找不到我的错误。你能帮我解决一下吗?

提前致谢!

1 个答案:

答案 0 :(得分:0)

当您在Structure传递时,请不要使用Structure.getPointer(),除非您必须这样做。当您这样做时,JNA无法自动同步本机和Java数据,并且它容易出错,以便记住自己在哪里这样做。在您的情况下,在您调用setupApi.SetupDiSetClassInstallParams时,Java字段中的任何内容都不会被复制到本机内存。

将您的功能映射更改为:

boolean SetupDiSetClassInstallParams(WinNT.HANDLE hDevInfo, SP_DEVINFO_DATA deviceInfoData, SP_CLASSINSTALL_HEADER classInstallHeader, int size);

并将调用更改为:

setupApi.SetupDiSetClassInstallParams(hDevInfo, device.getSPDeviceInfoData(), classInstallHeaderReference,             spPropChangeParamsSize);

修改

如果您坚持原始的struct定义(其中SP_CLASSINSTALL_HEADER是一个字段),则需要向接口添加一个函数映射(扩展接口并创建自己的本机库实例):

public interface MySetupApi extends SetupApi {
    MySetupApi INSTANCE = (MySetupApi)Native.loadLibrary(MySetupApi.class, W32APIOptions.DEFAULT_OPTIONS);
    boolean SetupDiSetClassInstallParams(WinNT.HANDLE hDevInfo, SP_DEVINFO_DATA deviceInfoData, SP_PROPCHANGE_PARAMS propChangeParams, int size);
}