调用Windows原生函数IsTpmReady抛出‘信号量发布过多’错误排查
问题分析与修复方案
主要问题点
- 参数类型不匹配:Windows API中
TpmIsReady的输出参数是BOOL*(对应Go的syscall.BOOL*,本质是int32类型),你代码中使用byte类型作为输出变量,会导致内存读写异常或返回值解析错误。 - 错误判断逻辑可优化:虽然检查
err == syscall.Errno(0)能覆盖成功场景,但更规范的方式是直接利用Windows API的返回值判断(TpmIsReady返回HRESULT,成功为S_OK即0)。
修正后的代码
package windows import ( "log" "syscall" "unsafe" ) const DEBUG = true // 根据实际需求调整 var ( TPMDLL = syscall.NewLazyDLL("TpmCoreProvisioning.dll") TpmReady = TPMDLL.NewProc("TpmIsReady") ) func IsTpmReady() (bool, error) { var enabled syscall.BOOL // 调用函数,传入BOOL类型变量的指针 hr, _, err := TpmReady.Call(uintptr(unsafe.Pointer(&enabled))) // HRESULT成功判断:S_OK为0 if hr == 0 { return enabled != 0, nil } if DEBUG { log.Printf("IsTpmReady调用失败: HRESULT=0x%x, 错误信息: %v", hr, err) } return false, err }
额外注意事项
- 确保程序与系统位数匹配:如果是64位系统,编译Go程序时使用
GOARCH=amd64;32位系统则用GOARCH=386,避免DLL加载的位数不兼容问题。 - 部分Windows版本可能未包含
TpmCoreProvisioning.dll,可以先检查系统目录(C:\Windows\System32)中是否存在该文件。
内容的提问来源于stack exchange,提问作者H. Ross
相关产品推荐
相关产品推荐

