You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 07:50:48