JNA绑定Win32的DwmGetColorizationColor函数返回E_INVALIDARG错误排查
你的问题里两个错误码指向核心问题:ERROR_PROC_NOT_FOUND(127)说明JNA找不到目标函数,而E_INVALIDARG多是函数查找失败后JNA默认返回的错误HRESULT,属于次生问题。下面分点拆解可能的原因和解决步骤:
1. 动态链接库指定错误
DwmGetColorizationColor属于dwmapi.dll,如果绑定接口时写错库名(比如写成dwmapi32.dll、dwm.dll),会导致JNA加载错误的库,自然找不到目标函数。
正确的库加载方式:
import com.sun.jna.Library; import com.sun.jna.Native; public interface DwmApi extends Library { // 正确加载系统的dwmapi.dll DwmApi INSTANCE = Native.load("dwmapi", DwmApi.class); }
2. 函数名拼写或匹配错误
Win32导出函数名称必须严格匹配MSDN定义的DwmGetColorizationColor,虽然Windows动态库对大小写不敏感,但建议完全一致避免意外。如果绑定的方法名写错(比如少写字母、大小写错误),JNA会无法定位到函数。
3. 函数签名(参数/返回值)不匹配
MSDN给出的函数签名是:
HRESULT DwmGetColorizationColor(
DWORD *pcrColorization,
BOOL *pfOpaqueBlend
);
JNA绑定必须严格对应类型:
- 返回值
HRESULT对应JNA的int类型 DWORD*是指向32位无符号整数的指针,对应JNA的IntByReferenceBOOL*是指向布尔值的指针,对应JNA的BooleanByReference
如果参数用了普通的int/boolean而非指针类型,或者返回值用了long,会导致JNA无法正确匹配函数,进而触发找不到函数的错误。
正确的绑定与调用示例
import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.ptr.BooleanByReference; import com.sun.jna.ptr.IntByReference; public interface DwmApi extends Library { DwmApi INSTANCE = Native.load("dwmapi", DwmApi.class); // 严格匹配MSDN的函数签名 int DwmGetColorizationColor(IntByReference pcrColorization, BooleanByReference pfOpaqueBlend); } // 调用代码 public class Main { public static void main(String[] args) { IntByReference colorRef = new IntByReference(); BooleanByReference opaqueRef = new BooleanByReference(); int hResult = DwmApi.INSTANCE.DwmGetColorizationColor(colorRef, opaqueRef); if (hResult == 0) { // S_OK表示调用成功 System.out.println("着色颜色: 0x" + Integer.toHexString(colorRef.getValue())); System.out.println("是否使用不透明混合: " + opaqueRef.getValue()); } else { System.err.println("HRESULT错误码: 0x" + Integer.toHexString(hResult)); System.err.println("系统错误码: " + Native.getLastError()); } } }
4. 系统版本不兼容
DwmGetColorizationColor是Windows Vista及以上版本才有的函数,如果你的程序运行在Windows XP或更早的系统中,dwmapi.dll里根本没有这个函数,必然会报找不到的错误。请确认运行环境的Windows版本符合要求。
额外提示
如果你使用JNA的jna-platform依赖包,里面已经封装了现成的Dwmapi类(com.sun.jna.platform.win32.Dwmapi),可以直接调用其中的DwmGetColorizationColor方法,不用自己手写绑定,能避免很多低级错误。
内容的提问来源于stack exchange,提问作者LonelyDoor

