因此,我嘗試通過動態加載在 C++ 項目上運行我的 go 代碼。它工作得很好,除了返回值上有一些不需要的字符串。正如我解釋的那樣,我從 Go 那里得到了一些不需要的信息。我的代碼:package mainimport "C"func main() {}//export GetTestStringfunc 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..."
1 回答

冉冉說
TA貢獻1877條經驗 獲得超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
}
- 1 回答
- 0 關注
- 129 瀏覽
添加回答
舉報
0/150
提交
取消