Cadena desconocida de Golang cargada dinámicamente hacia CPP
Entonces, intenté ejecutar mi código Go en un proyecto C++ con carga dinámica. Funciona muy bien, excepto que hay una cadena no deseada en el valor devuelto. Como expliqué antes, obtuve algunas información no deseadas de Go.
Mi código Go:
package main
import "C"
func main() {}
//export GetTestString
func GetTestString() string {
return "test"
}
Lo construyo con:
go build -buildmode=c-shared -o test.so test.go
Cargo dinámicamente en mi proyecto CPP con esta función:
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);
}
// resuelvo el símbolo getTestString y lo asigno a un puntero de función
auto getTestString = (GoString (*)())dlsym(handle, "GetTestString");
if ((error = dlerror()) != NULL) {
fputs(error, stderr);
exit(1);
}
// llamo a GetTestString()
GoString testString = (*getTestString)();
printf("%s\n", testString.p);
// cierro el archivo cuando haya terminado
dlclose(handle);
}
La salida es:
“test”true …\n HT= Ha= Hg= MB, Wa= and cnt= ha= hg= ht= max= ptr siz= tab= top= ua= u_g=, …, fp:argp=falsefaultgcingpanicsleepsse41sse42ssse3 (MB)\n addr= base code= ctxt: curg= goid jobs= list= m->p= next= p->m= prev= span= varp=(…)\n, not 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…”
davy.ai
Parece que la salida no solo es la cadena esperada “test”, sino que también contiene información adicional no deseada. Esto podría ser debido a varios motivos, como una asignación de memoria incorrecta o una incompatibilidad entre los tipos de datos de C++ y Go.
Una posible solución es utilizar el tipo de dato
const char*
de C en lugar del tipostring
de Go para el tipo de retorno de la funciónGetTestString
. Esto se puede lograr modificando el código de Go de la siguiente manera:Luego, en el código de C++, podemos actualizar la definición de la estructura
GoString
para que utiliceconst char*
en lugar destring
. Además, debemos liberar la memoria asignada porC.CString()
una vez que hayamos terminado de usar la cadena devuelta.Con estos cambios, la salida solo debería contener la cadena esperada “test”.