英文:
how can I get the data pointer of a string variable in go?
问题
我想要获取一个字符串变量的数据指针(类似于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]))))
英文:
I want to get the data pointer of a string variable(like string::c_str() in c++) to pass to a c function and I found this doesn't work:
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]))))
}
Compile error info is: 'cannot take the address of s[0]'.
This will be OK I but I doubt it will cause unneccesary memory apllying. Is there a better way to get the data pointer?
C.Println((*C.char)(unsafe.Pointer(&([]byte(s)[0]))))
答案1
得分: 2
有一种方法可以在不复制的情况下从Go字符串获取底层数据到C中。它不会作为C字符串工作,因为它不是C字符串。即使你设法提取指针,你的printf也不会起作用,即使有时它可能会工作。Go字符串不是C字符串。在Go使用更多的libc时,它们曾经是为了兼容性而存在,但现在不再是了。
只需按照cgo手册的指示使用C.CString。如果你为了效率而奋斗,那么不使用cgo会获得更大的收益,因为调用C的开销比分配一些内存和复制一个字符串要大得多。
英文:
There are ways to get the underlying data from a Go string to C without copying it. It will not work as a C string because it is not a C string. Your printf will not work even if you manage to extract the pointer even if it happens to work sometimes. Go strings are not C strings. They used to be for compatibility when Go used more libc, they aren't anymore.
Just follow the cgo manual and use C.CString. If you're fighting for efficiency you'll win much more by just not using cgo because the overhead of calling into C is much bigger than allocating some memory and copying a string.
答案2
得分: 0
(*reflect.StringHeader)(unsafe.Pointer(&sourceTail)).Data
在Go语言中,字符串不以空字符结尾,因此在传递给对应的C函数时,你应该始终传递Data和Len参数。C标准库中有一系列函数用于处理这种类型的字符串,例如,如果你想用printf格式化它们,格式说明符应该是%.*s而不是%s,并且你需要在参数列表中同时传递长度和指针。
英文:
(*reflect.StringHeader)(unsafe.Pointer(&sourceTail)).Data
Strings in go are not null terminated, therefore you should always pass the Data and the Len parameter to the corresponding C functions. There is a family of functions in the C standard library to deal with this type of strings, for example if you want to format them with printf, the format specifier is %.*s instead of %s and you have to pass both, the length and the pointer in the arguments list.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论