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

因此,我尝试通过动态加载在 C++ 项目上运行我的 go 代码。它工作得很好,除了返回值上有一些不需要的字符串。正如我解释的那样,我从 Go 那里得到了一些不需要的信息。


我的代码:


package main


import "C"


func main() {}


//export GetTestString

func GetTestString() string {

    return "test"

}

我用以下方式构建它: go build -buildmode=c-shared -o test.so test.go


使用此功能将其动态加载到我的 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);

}

输出是:


" test true ...\n H_T= H_a= H_g= MB, W_a= and cnt= h_a= h_g= h_t= max= ptr siz= tab= top= u_a= u_g=, ..., fp:argp=falsefaultgcingpanicsleepsse41sse42ssse3 (MB)\n addr= base code= ctxt: curg= goid jobs= list= m->p= next= p->m= prev= span= varp=(...)\n, 不是 SCHED efenceerrno objectpopcntscvg: selectsweep (scan (scan) MB in Dying= locks= m->g0= nmsys= s=nil\n, goid=, size=, sys: GODEBUGIO waitSignal \ttypes \tvalue=cs fs gctracegs panic: r10 r11 r12 r13 r14 r15 r8 r9 rax rbp rbx rcx rdi rdx rflags rip rsi rsp runningsignal syscallunknownwaiting etypes goalΔ= is not mcount= minutes nalloc= newval= nfree..."


慕容708150
浏览 131回答 1
1回答

冉冉说

通过指向 C 的指针传递字符串时,您需要使用 length ( n) inGoString来获取正确数量的字符,因为字符串 atp未\0终止。或者您可以返回*C.char而不是string使用C.CString()在 C 堆上分配副本(然后您负责在使用后释放)。请参阅此处的Cgo 文档。您的代码中发生的事情是printf()简单地打印从指向的位置开始的所有字符,string.p直到它到达\0终止符 - 这就是为什么您在test.因此,您可以执行以下任一操作:printf("%.*s\n", testString.n, testString.p);(但请注意,大多数对预期\0终止的 C 字符串进行操作的函数将无法在此指针上工作,除非它们也占用字符串的长度)或将 Go 部分更改为这样的内容,然后free()在 C 端使用后使用指针:func GetTestString() *C.char {    return C.CString("test") // CString will allocate string on C heap}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go