登录
首页 >  Golang >  Go问答

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

来源:SegmentFault

时间:2023-01-10 20:13:41 297浏览 收藏

亲爱的编程学习爱好者,如果你点开了这篇文章,说明你对《Go调用DLL时, 返回值是char*时如何接收返回值?》很感兴趣。本篇文章就来给大家详细解析一下,主要介绍一下go、CGO、DLL,希望所有认真读完的童鞋们,都有实质性的提高。

问题内容

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的,更可靠的写法.

正确答案

我现在的写法能拿到数据,但是会不会导致内存泄漏?并发下是否会有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 文档主要部分通读一遍。

终于介绍完啦!小伙伴们,这篇关于《Go调用DLL时, 返回值是char*时如何接收返回值?》的介绍应该让你收获多多了吧!欢迎大家收藏或分享给更多需要学习的朋友吧~golang学习网公众号也会发布Golang相关知识,快来关注吧!

声明:本文转载于:SegmentFault 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>
评论列表