调用Windows DLL的C代码转Go失败,求解决方案
问题分析与解决
你的Go代码无法正确获取DLL中导出变量G的值,核心错误在于对GetProcAddress返回值的处理逻辑错误。以下是具体问题和修正方案:
错误原因
在C代码中,GetProcAddress直接返回导出变量G的内存地址,你将其转换为double*后 Dereference 即可得到值。但在你的Go代码中:
real_G := (*float64)(unsafe.Pointer(&mdl_G))
这里错误地取了mdl_G变量自身的地址(而非mdl_G存储的DLL变量地址),导致最终指向的是栈上的uintptr值,而非DLL中的double变量。
修正后的Go代码
package main import ( "log" "syscall" "unsafe" ) func main() { // 加载DLL并处理错误 dll, err := syscall.LoadDLL("./test_win64.dll") if err != nil { log.Fatalf("加载DLL失败: %v", err) } defer dll.Release() // 确保程序退出时释放DLL资源 // 获取导出变量G的地址并处理错误 mdl_G, err := syscall.GetProcAddress(dll.Handle, "G") if err != nil { log.Fatalf("获取变量G地址失败: %v", err) } // 将DLL变量地址转换为float64指针并取值 real_G := (*float64)(unsafe.Pointer(mdl_G)) log.Printf("G = %.2f", *real_G) }
关键修正点
- 正确转换地址:直接将
mdl_G(DLL变量的内存地址)转换为unsafe.Pointer,再转为*float64,而非取mdl_G自身的地址 - 错误处理:添加了DLL加载和地址获取的错误检查,便于排查问题
- 资源释放:使用
defer dll.Release()确保DLL资源被正确释放
额外注意事项
- 确保你的Go程序编译为64位(与
test_win64.dll的架构匹配) - 确保
test_win64.dll位于程序运行时的当前目录,或使用完整路径 - 确认DLL中确实导出了名为
G的double类型变量
内容的提问来源于stack exchange,提问作者Mingut
相关产品推荐
相关产品推荐

