DLL里的代码
char *echo() {
return "123123";
}
这是我现在的写法.
package main
import (
"fmt"
"strings"
"syscall"
"unsafe"
)
func main() {
dll := syscall.MustLoadDLL("my_dll.dll")
r1, _, _ := dll.MustFindProc("echo").Call()
fmt.Println(GoString(r1))
}
func GoString(p uintptr) string {
ans := strings.Builder{}
for {
ptr := unsafe.Pointer(p)
b := *(*byte)(ptr)
if b == 0 {
return ans.String()
}
ans.WriteByte(b)
p += 1
}
}
- DLL里代码没法改
- 实际情况下,echo会返回通过网络请求得到的字符串,而不是固定的.
- 我现在的写法能拿到数据,但是会不会导致内存泄漏?并发下是否会有bug?
ptr := unsafe.Pointer(p)
这一行有possible misuse Unsafe.Pointer的warning,是否有问题?- 请教一下有无更好的,正确的,无warning的,更可靠的写法.
会泄露,从 DLL 里拿到的内存没释放。并发要看 DLL 给的函数本身支不支持,不支持的话就在 Go 里加锁,性能会差很多。
参考这个
要不要试试用 CGO?如果会一点 C 的话写 CGO 还是比较容易的。
文档
只是简单的 wrapper 的话用 CGO 还是能很快上手胜任的。
另外就是 C 和 Go 的内存管理差别挺大的,用起来要格外注意,直接互传指针会出问题。建议务必先把 CGO 文档主要部分通读一遍。