使用dlsym调用Go导出函数时仅传递字符串首字符的问题解决
CGo调用动态库字符串截断问题解决
问题现象
当C代码传入字符串"hello world"调用Go编译的动态库时,Go侧的ReadFromCMD函数仅输出第一个字符"h",无法完整输出目标字符串。
原代码
C调用代码
#cgo LDFLAGS: -ldl #include <stdio.h> #include <stdlib.h> #include <dlfcn.h> #include <string.h> void cmd_read(const char *c) { void (*go)(char*); void *h; char *error; h = dlopen("./cgo_cmd.so", RTLD_LAZY); if (!h) { fprintf(stderr, "Error: %s\n", dlerror()); return; } go = dlsym(h, "ReadFromCMD"); if ((error = dlerror()) != NULL) { fputs(error, stderr); exit(1); } go(c); dlclose(h); }
原Go导出函数
func ReadFromCMD(path string) { fmt.Printf(path) }
问题根源
Go字符串与C字符串的内存结构不兼容:C字符串是以\0结尾的字符数组,仅通过指针传递;而Go字符串包含长度字段和指针字段两部分。直接将C字符串指针传递给接收Go字符串类型的函数,会导致Go错误解析内存,仅读取到第一个字符。
修复方案
调整Go导出函数的参数类型,改用*C.char接收C字符串,再通过C.GoString()将其转换为合法的Go字符串,即可完整读取内容。
修改后的Go导出函数
//export ReadFromCMD func ReadFromCMD(path *C.char) { p := fmt.Sprintf("%s", C.GoString(path)) fmt.Println(p) }
内容的提问来源于stack exchange,提问作者Pandy Yang
相关产品推荐
相关产品推荐

