Go调用dll 解决方案 dll查看工具

  • Post author:
  • Post category:其他


准备工作

Go需要1.10版本,即支持动态链接库

基本调用代码

lib := syscall.NewLazyDLL("lib/plugin.dll") // 读取dll
f := lib.NewProc("Sum") // 调用dll函数
res, _, _ := f.Call(param) // 传值
fmt.Println(res)

可能出现的问题

%1 is not a valid Win32 application

这是由于调用的dll位数和系统版本位数不一致导致的,需要设置成与dll位数相同的编译环境,在cmd中使用以下命令

go env // 查看set GOARCH,如果系统是64位,则等于amd64,如果是32,则是386
go env -w GOARCH=386 // 设置32编译环境
go env -w GOARCH=amd64 // 设置64编译环境
 

The specified module could not be found

这个问题分为三种情况

dll路径不对

调整路径即可

dll依赖别的dll,依赖的dll缺失了



下载DependenciesGui,

https://github.com/lucasg/Dependencies

打开后,菜单栏点击file->open,选择需要查看的dll

在这里插入图片描述

当出现红色感叹号时,则说明缺失这个dll,就需要将这个缺失的dll放在与选择的dll同目录,解决后

这个dll本身有依赖的dll,且dll与依赖dll在同一目录,但是go业务代码与dll,被依赖的dll不在同一目录,

把dll,被依赖的所有dll与业务代码放在同一目录

数据类型问题

当传值或者接收值时,f.Call(param)。所有值的类型应该都是uintptr,应该注意数据类型的转换,以下代码仅做参考:

// string到uintptr.
func StrPtr(s string) uintptr {
	p, _ := syscall.UTF16PtrFromString(s)
	return uintptr(unsafe.Pointer(p))
}

// uintptr到string.
func PtrStr(p uintptr) string {
	return syscall.UTF16ToString(*(*[]uint16)(unsafe.Pointer(&p)))
}

// bool到uintptr.
func BoolPtr(b bool) uintptr {
	if b {
		return uintptr(1)
	}
	return uintptr(0)
}

// float32到uintptr.
func Float32Ptr(f float32) uintptr {
	return uintptr(*(*uint32)(unsafe.Pointer(&f)))
}

// uintptr到float32.
func PtrToFloat32(p uintptr) float32 {
	u := uint32(p)
	return *(*float32)(unsafe.Pointer(&u))
}

// int到uintptr
func IntPtr(i int) uintptr {
	return uintptr(i)
}

// int到uintptr
func PtrInt(u uintptr) int {
	return int(u)
}
 

示例代码

package main

import (
	"fmt"
	"syscall"
)

var (
	ta        = syscall.NewLazyDLL("AIO_API.dll")
	taInit3   = ta.NewProc("TA_Init3")
	taConsume = ta.NewProc("TA_Consume")
)

func main() {
	aio()
}

func aio() {
	str := StrPtr("str")
	i := IntPtr(123)
	b := BoolPtr(true)
	// 调用接口示例
	res, _, _ := taConsume.Call(str, i, b)
    fmt.Printf("%v", IntPtr(res))
}

目录结构

在这里插入图片描述



版权声明:本文为shelutai原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。