当前位置: 首页 > 知识库问答 >
问题:

从动态加载的Golang到CPP的未知字符串

房冥夜
2023-03-14

所以,我试着用动态加载在C项目上运行我的go代码。它工作得很好,只是返回值中有一些不需要的字符串。正如我解释的那样,我从Go那里得到了一些不需要的信息。

我的go代码:

package main

import "C"

func main() {}

//export GetTestString
func GetTestString() string {
    return "test"
}

我用:go build-buildmode=c-shared-o测试来构建它。所以测试一下。开始

使用此功能将其动态加载到我的CPP项目上:

typedef struct { const char *p; ptrdiff_t n; } GoString;

void getTestString() {
    void *handle;
    char *error;
    handle = dlopen ("./test.so", RTLD_LAZY);
    if (!handle) {
        fputs (dlerror(), stderr);
        exit(1);
    }

    // resolve getTestString symbol and assign to fn ptr
    auto getTestString = (GoString (*)())dlsym(handle, "GetTestString");
    if ((error = dlerror()) != NULL)  {
        fputs(error, stderr);
        exit(1);
    }

    // call GetTestString()
    GoString testString = (*getTestString)();
    printf("%s\n", testString.p);

    // close file handle when done
    dlclose(handle);
}

输出为:

“testtrue…\n H\u T=H\u a=H\u g=MB,W\u a=and cnt=H\u a=H\u g=H\u T=max=ptr siz=tab=top=u\u a=u\u g=,…,fp:argp=falsefaultgcingpanicsleepsse41sse42ssse3(MB)\n addr=base code=ctxt:curg=goid jobs=list=m-

共有1个答案

鞠鸿雪
2023-03-14

当通过指向C的指针传递字符串时,您需要使用GoString中的长度(n)来获取正确数量的字符作为p处的字符串不是\0终止。或者您可以返回*C. char而不是string并使用C. CString()在C堆上分配副本(然后您负责在使用后释放)。请参阅此处的Cgo留档。

代码中发生的事情是printf()简单地打印从string. p指向的位置开始的所有字符,直到它到达\0终止符-这就是为什么您在test之后看到内存内容的原因。

因此,您可以执行以下任一操作:

printf("%.*s\n", testString.n, testString.p);

(但请注意,大多数对预计将被\0终止的C字符串进行操作的函数将无法在此指针上运行,除非它们也采用字符串长度)

或者在C端使用后,将Go部分更改为类似这样的内容,然后将指针更改为free()

golang prettyprint-override">func GetTestString() *C.char {
    return C.CString("test") // CString will allocate string on C heap
}
 类似资料:
  • 我有一个表单,它首先加载文本字段,并有一个与之关联的时间选择器。用户还可以单击“更多”按钮,该按钮动态加载下面的额外文本字段。这也有一个与之相关联的时间选择器,但是它不会加载到动态字段上。我正在使用Trent Richardson的jQuery timepicker插件http://trentrichardson.com/examples/timepicker 我还找到了以前的答案(https:/

  • 问题内容: 相反,如果不从文件加载xml,如何从字符串加载呢? 问题答案: 您的XML字符串在哪里。有关更多信息,请参见MSDN文章。

  • 我有一个问题,我不能从一个对象加载3个属性显示在表视图上。我有一个付款对象,它由一个受益人对象(包括3个字符串-name、accountnumber和code)、一个金额字符串和一个引用字符串组成。如果这些项目都是同一个对象的一部分,我可以查看它们,但是当我将它们拆分时,它不会引起问题,并且单元格是空的。 每次我尝试将付款加载到tableView时,只有金额和引用是可见的。我尝试使用Propert

  • 问题内容: 我从文件中读取了编码为“ UTF-8”的字符串。我需要将其与表达式匹配。文件的第一个字符为,但字符串中的第一个字符为(空符号)。我已经将其翻译为具有字符集“ UTF-8”的字节,这里是。有谁知道它是什么以及如何使用正则表达式解决它? 问题答案: 一些编辑器(如记事本)在保存UTF-8文本时会添加BOM(字节顺序掩码)签名。从此类文件中读取字符串之前,应检查0xEF,0xBB,0xBF字

  • 问题内容: 我有一个作为参数的方法,我需要在此切片前添加。方法如下: 当我尝试不起作用时: 在这种情况下,正确的前置方式是什么? 问题答案: 只能附加与切片的元素类型匹配的类型的值: 所以,如果你有元素,你必须包装您最初的以能够使用: 输出(在Go Playground上尝试):

  • 问题内容: 我有以下代码将数据从stdout输出到文件: 我需要将输出从stdout转换为字符串值而不是文件。我该如何实现? 可能还有另一个函数可以让我将io.Copy行更改为io.Copy(myStringVariable,stdoutPipe),因为我需要读取命令的输出并对其进行一些处理? 提前致谢 问题答案: 您不需要管道,编写器,goroutine等。只需使用Cmd.Output 您可以将