Go调用DLL时, 返回值是char*时如何接收返回值?

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
    }
}
  1. DLL里代码没法改
  2. 实际情况下,echo会返回通过网络请求得到的字符串,而不是固定的.
  3. 我现在的写法能拿到数据,但是会不会导致内存泄漏?并发下是否会有bug?
  4. ptr := unsafe.Pointer(p)这一行有possible misuse Unsafe.Pointer的warning,是否有问题?
  5. 请教一下有无更好的,正确的,无warning的,更可靠的写法.
阅读 5.1k
1 个回答
我现在的写法能拿到数据,但是会不会导致内存泄漏?并发下是否会有bug?

会泄露,从 DLL 里拿到的内存没释放。并发要看 DLL 给的函数本身支不支持,不支持的话就在 Go 里加锁,性能会差很多。

ptr := unsafe.Pointer(p)这一行有possible misuse Unsafe.Pointer的warning,是否有问题?

参考这个

请教一下有无更好的,正确的,无warning的,更可靠的写法.

要不要试试用 CGO?如果会一点 C 的话写 CGO 还是比较容易的。

文档

A few special functions convert between Go and C types
by making copies of the data. In pseudo-Go definitions:
// Go string to C string
// The C string is allocated in the C heap using malloc.
// It is the caller's responsibility to arrange for it to be
// freed, such as by calling C.free (be sure to include stdlib.h
// if C.free is needed).
func C.CString(string) *C.char

// Go []byte slice to C array
// The C array is allocated in the C heap using malloc.
// It is the caller's responsibility to arrange for it to be
// freed, such as by calling C.free (be sure to include stdlib.h
// if C.free is needed).
func C.CBytes([]byte) unsafe.Pointer

// C string to Go string
func C.GoString(*C.char) string

// C data with explicit length to Go string
func C.GoStringN(*C.char, C.int) string

// C data with explicit length to Go []byte
func C.GoBytes(unsafe.Pointer, C.int) []byte

只是简单的 wrapper 的话用 CGO 还是能很快上手胜任的。

另外就是 C 和 Go 的内存管理差别挺大的,用起来要格外注意,直接互传指针会出问题。建议务必先把 CGO 文档主要部分通读一遍。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题