【问题标题】:how can I get the data pointer of a string variable in go?如何在go中获取字符串变量的数据指针?
【发布时间】:2017-07-17 17:17:52
【问题描述】:

我想将字符串变量的数据指针(如 c++ 中的 string::c_str())传递给 c 函数,但我发现这不起作用:

package main

/*
#include <stdio.h>
void Println(const char* str) {printf("%s\n", str);}
*/
import "C"

import (
    "unsafe"
)

func main() {
    s := "hello"
    C.Println((*C.char)(unsafe.Pointer(&(s[0]))))
}

编译错误信息是:'cannot take the address of s[0]'。 这没关系,但我怀疑它会导致不必要的内存应用。有没有更好的方法来获取数据指针?

C.Println((*C.char)(unsafe.Pointer(&([]byte(s)[0]))))

【问题讨论】:

    标签: pointers go cgo


    【解决方案1】:

    有一些方法可以将底层数据从 Go 字符串获取到 C 而无需复制。它不能作为 C 字符串工作,因为它不是 C 字符串。即使您设法提取指针,即使它有时会起作用,您的 printf 也不会起作用。 Go 字符串不是 C 字符串。当 Go 使用更多的 libc 时,它们曾经是为了兼容性,现在已经不是了。

    只需按照 cgo 手册并使用C.CString。如果您正在为效率而战,那么不使用 cgo 会赢得更多,因为调用 C 的开销比分配一些内存和复制字符串要大得多。

    【讨论】:

    • 是你的最后一句话——“调用 C 的开销比分配一些内存和复制字符串要大得多”——你有任何基准来支持它吗?
    • @Not_a_Golfer 事实上,我愿意。从一年前开始:github.com/art4711/cgo_overhead 如果我有时间,我会更新到 1.8。
    • 为 1.8 更新。在 1.8 中,与 Go 函数调用相比,进行 cgo 函数调用的速度仅慢 36 倍,而不是 92 倍。
    • 耶稣!我不知道它这么贵。这是什么原因造成的?
    • @Not_a_Golfer 很多事情。它需要更改堆栈,许多正常的“此函数不使用堆栈”优化被禁用,运行一堆东西以确保我们没有违反垃圾收集器规则(即使 C 函数不使用论据)等。
    猜你喜欢
    • 2019-07-06
    • 2015-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-07
    • 2014-02-22
    • 2019-07-07
    相关资源
    最近更新 更多