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

如何将C++的const char[]或std::string正确转换为Go的GoString?

解决C++与Go互调时的字符串类型转换问题

问题背景

要从C++调用Go实现的语言检测函数,Go代码如下:

// basic.go
package main

import "C"

import (
    "github.com/pemistahl/lingua-go"
)

var lan lingua.Language

//export Langdetectfunct
func Langdetectfunct(text string) int {
    detector := lingua.NewLanguageDetectorBuilder().
        FromAllLanguages().
        Build()

    if language, exists := detector.DetectLanguageOf(text); exists {
        lan = language
    }
    lan = lingua.English

    return int(lan)
}

func main() {}

使用c-shared模式编译生成共享库:

go build -o basic.so -buildmode=c-shared basic.go

尝试在C++中调用时,无论是直接用字符串字面量赋值GoString,还是传入std::string,都会出现类型转换错误:

  • 用字符串字面量赋值时错误:
    error: conversion from ‘const char [22]’ to non-scalar type ‘GoString’ {aka ‘_GoString_’} requested
    
  • 传入std::string时错误:
    error: could not convert ‘text’ from ‘std::string’ {aka ‘std::__cxx11::basic_string<char>’} to ‘GoString’ {aka ‘_GoString_’}
    

解决方案

Go生成的头文件中,GoString是一个结构体,定义大致如下:

typedef long long GoInt;
typedef struct { const char *p; GoInt n; } GoString;

它包含两个字段:p是字符串指针,n是字符串长度。需要手动构造该结构体,不能直接用C++字符串类型赋值。

1. 从C++字符串转换为GoString

从const char[]转换

直接用字符串指针和strlen获取的长度构造GoString:

const char* c_text = "Languages are awesome";
GoString go_text = {c_text, strlen(c_text)};

从std::string转换

利用std::string的c_str()方法获取指针,size()方法获取长度:

std::string cpp_text = "Languages are awesome";
GoString go_text = {cpp_text.c_str(), static_cast<GoInt>(cpp_text.size())};

修改后的完整C++代码:

#include "basic.h"
#include <iostream>
#include <cstring> // 用于strlen函数

int main() {
    // 从const char[]转换调用
    const char* c_text = "Languages are awesome";
    GoString go_text1 = {c_text, strlen(c_text)};
    int res1 = Langdetectfunct(go_text1);
    std::cout << "res1: " << res1 << std::endl;

    // 从std::string转换调用
    std::string cpp_text = "Languages are awesome";
    GoString go_text2 = {cpp_text.c_str(), static_cast<GoInt>(cpp_text.size())};
    int res2 = Langdetectfunct(go_text2);
    std::cout << "res2: " << res2 << std::endl;

    return 0;
}

2. 从GoString转换为C++字符串

如果需要将Go返回的GoString转换为C++类型:

  • 转换为std::string:直接利用std::string的构造函数,指定指针和长度:
    std::string cpp_str(go_str.p, go_str.n);
    
  • 转换为const char[]:直接使用go_str.p即可,但要注意内存生命周期,避免引用Go已回收的内存。

编译注意事项

编译C代码时,不要用C语言的标准参数-std=c17,应该用C的标准参数:

g++ -std=c++17 -o basic basic1.cpp ./basic.so

内容的提问来源于stack exchange,提问作者Raphael10

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 14:01:13