Dart FFI使用lookupFunction报错:Uint32函数需为int函数子类型
问题
在Dart中调用psapi.dll的GetWindowThreadProcessId函数时,出现类型不匹配错误:
‘The type 'Uint32 Function(IntPtr, Pointer
)' must be a subtype of 'int Function(IntPtr, Pointer )' for 'lookupFunction'’
出错代码示例:
class Psapi { static final ffi.DynamicLibrary psapi = ffi.DynamicLibrary.open('psapi.dll'); static int GetWindowThreadProcessId( ffi.IntPtr hwnd, ffi.Pointer<ffi.Uint32> lpdwProcessId) { return psapi.lookupFunction<ffi.Uint32 Function(ffi.IntPtr hwnd, ffi.Pointer<ffi.Uint32> lpdwProcessId), int Function(ffi.IntPtr hwnd, ffi.Pointer<ffi.Uint32> lpdwProcessId)>('GetWindowThreadProcessId')( hwnd, lpdwProcessId, ); } }
原因分析
Dart FFI的lookupFunction要求两个类型参数必须严格兼容:第一个是原生DLL函数的签名类型,第二个是Dart侧调用时使用的签名类型。这里的错误核心是:原生签名返回的ffi.Uint32与Dart侧期望的int不属于直接兼容的子类型,导致类型校验失败。
解决方法
需要让原生签名和Dart侧签名的返回类型保持一致,有两种可行方案:
方案一:统一使用ffi.Uint32作为返回类型
调整Dart侧函数的返回类型为ffi.Uint32,确保lookupFunction的两个签名返回类型完全匹配:
class Psapi { static final ffi.DynamicLibrary psapi = ffi.DynamicLibrary.open('psapi.dll'); static ffi.Uint32 GetWindowThreadProcessId( ffi.IntPtr hwnd, ffi.Pointer<ffi.Uint32> lpdwProcessId) { return psapi.lookupFunction<ffi.Uint32 Function(ffi.IntPtr, ffi.Pointer<ffi.Uint32>), ffi.Uint32 Function(ffi.IntPtr, ffi.Pointer<ffi.Uint32>)>('GetWindowThreadProcessId')( hwnd, lpdwProcessId, ); } }
方案二:统一使用int作为返回类型
将原生签名的返回类型改为ffi.Int(Dart的int与FFI的Int类型直接兼容),与Dart侧签名保持一致:
class Psapi { static final ffi.DynamicLibrary psapi = ffi.DynamicLibrary.open('psapi.dll'); static int GetWindowThreadProcessId( ffi.IntPtr hwnd, ffi.Pointer<ffi.Uint32> lpdwProcessId) { return psapi.lookupFunction<ffi.Int Function(ffi.IntPtr, ffi.Pointer<ffi.Uint32>), int Function(ffi.IntPtr, ffi.Pointer<ffi.Uint32>)>('GetWindowThreadProcessId')( hwnd, lpdwProcessId, ); } }
说明:两种方案均可解决类型不匹配问题,选择取决于业务场景。若需要严格对应原生函数的无符号32位返回值,优先选方案一;若更倾向于使用Dart原生int类型处理逻辑,方案二更合适。
内容的提问来源于stack exchange,提问作者Sharif Ahamed
相关产品推荐
相关产品推荐

