为了账号安全,请及时绑定邮箱和手机立即绑定

golang从dll获取char*作为返回值

golang从dll获取char*作为返回值

Go
慕运维8079593 2023-07-26 15:38:22
我正在使用 golang 调用 Dll 函数,例如char* fn(),该 dll 不是我自己编写的,我无法更改它。这是我的代码:package mainimport (    "fmt"    "syscall"    "unsafe")func main() {    dll := syscall.MustLoadDLL("my.dll")    fn := dll.MustFindProc("fn")    r, _, _ := fn.Call()    p := (*byte)(unsafe.Pointer(r))    // define a slice to fill with the p string    data := make([]byte, 0)    // loop until find '\0'    for *p != 0 {        data = append(data, *p)        // append 1 byte        r += unsafe.Sizeof(byte(0))    // move r to next byte        p = (*byte)(unsafe.Pointer(r)) // get the byte value    }    name := string(data) // convert to Golang string    fmt.Println(name)}我有一些疑问:有更好的方法吗?像这样的 dll 函数有数百个,我必须为所有函数编写循环。对于像100k+字节这样的非常长的字符串,会append()导致性能问题吗?解决了。原因unsafe.Pointer(r)linter govet显示警告possible misuse of unsafe.Pointer,但代码运行良好,如何避免此警告?解决方案:可以通过-unsafeptr=false在govet命令行中添加来解决,对于vim-ale,添加let g:ale_go_govet_options = '-unsafeptr=false'。
查看完整描述

2 回答

?
慕村9548890

TA贡献1884条经验 获得超4个赞

将 uintptr 转换为上指针是非法的。您必须阅读规则: https://golang.org/pkg/unsafe/#Pointer

但有一种 hacky 方法,不应该产生警告:

//go:linkname gostringn     runtime.gostringn

func gostringn(p uintptr, l int) string


//go:linkname findnull     runtime.findnull

//go:nosplit

func findnull(s uintptr) int


// ....


name := gostringn(r, findnull(r))

函数接受指针,但我们从运行时将它们链接为 uintptr,因为它们具有相同的 sizeof。


理论上可能有效。但也被人皱眉。


回到你的代码,你可以用一行代码来完成:


name := C.GoString((*C.char)(unsafe.Pointer(r)))


查看完整回答
反对 回复 2023-07-26
?
萧十郎

TA贡献1815条经验 获得超13个赞

我通过跟踪go源码得到了以下解决方案os.Args,但是我是基于go1.17。如果您是其他版本,可以阅读源码来解决。


func UintPtrToString(r uintptr) string {

    p := (*uint16)(unsafe.Pointer(r))

    if p == nil {

        return ""

    }


    n, end, add := 0, unsafe.Pointer(p), unsafe.Sizeof(*p)

    for *(*uint16)(end) != 0 {

        end = unsafe.Add(end, add)

        n++

    }

    return string(utf16.Decode(unsafe.Slice(p, n)))

}


查看完整回答
反对 回复 2023-07-26
  • 2 回答
  • 0 关注
  • 242 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信