query pattern index for create c go gccgo

pattern - Uso de Go on existing C project



search string mongodb (2)

Tengo un programa escrito completamente en C que usa archivos de objetos múltiples (.o) en él. Estos archivos están empaquetados dentro de un archivo de almacenamiento (.a) que, a su vez, se utiliza en tiempo de compilación del archivo principal (.c) programa.

Quiero escribir un nuevo archivo para este proyecto en Go. Mi idea es escribir este archivo .go y luego crear un archivo de objeto (.o) partir de él. Después, quiero poner este archivo de objeto dentro del archivo de archivo (.a) ya mencionado.

Esto básicamente significa que quiero llamar a las funciones Go desde un programa C. He leído esta pregunta , y aunque me mostró que lo que quiero es posible a través de GCCGO, no está 100% claro en cuanto a cómo hacerlo.

Incluso con las pruebas más básicas, recibo errores durante la fase de enlace. Más específicamente, aquí hay uno de esos ejemplos básicos:

printString.go

package main import ( "fmt" ) func PrintString(buff string) int { fmt.Printf(buff) return 1 }

c_caller.c

#define _GNU_SOURCE #include <stdio.h> extern int PrintString(char*) __asm__ ("print.main.PrintString"); int main() { char *string_to_pass= NULL; asprintf(&string_to_pass, "This is a test."); int result= PrintString(string_to_pass); if(result) {printf("Everything went as expected!/n");} else {printf("Uh oh, something went wrong!/n");} return result; }

Compilando

Para compilar el archivo Go, utilicé este comando:

gccgo -c printString.go -o printString.o -fgo-prefix=print -Wall -Werror -march=native

Para compilar todo, utilicé este comando:

gccgo -o main c_caller.c printString.o -Wall -Werror -march=native

El mensaje de devolución que recibo es:

/usr/lib64/libgo.so.4.0.0: undefined reference to `main.main'' /usr/lib64/libgo.so.4.0.0: undefined reference to `__go_init_main'' collect2: error: ld returned 1 exit status

Lo que significa que GCCGO espera una función principal en el archivo Go en lugar de la C.

El uso de las --static-libgo , --static-libgo y -Wl,-R,/path/to/libgo.so''s_folder en el segundo comando produce un resultado diferente:

/usr/bin/ld: cannot find -lgo collect2: error: ld returned 1 exit status

Lo cual no tiene sentido, ya que tengo la variable de entorno LD_LIBRARY_PATH apuntando correctamente a la carpeta de libgo.so.

Me doy cuenta de que probablemente estoy haciendo algo mal aquí, pero simplemente no puedo ver qué es eso. No hay ejemplos de GCCGO y su interacción con C, y la única referencia que pude encontrar fue esta página , que personalmente considero que no es suficiente.

Pido amablemente algunos consejos sobre este asunto y gracias por su tiempo. :)


Actualmente no hay una forma compatible para hacer lo que desea. Ir siempre necesita el soporte de su tiempo de ejecución, y el punto de entrada para eso siempre es main . AFAIK, gccgo también hace estos mismos supuestos, y no proporciona una forma de vincular fácilmente desde otros programas.

Si desea hacer esto de manera compatible, tendrá que esperar hasta go1.5 + donde se está trabajando para compilar bibliotecas compartidas desde el código Go.

Si realmente quieres piratear esto ahora, puedes ver cómo funciona el puerto Android usando la cadena de herramientas gc predeterminada con -linkmode external , que renombra main en el archivo objeto y lo llama externamente.


Puede que esto no sea lo que quieres, pero en Go 1.5, que llegará en agosto, podrás crear bibliotecas compatibles con C con la herramienta ir. Entonces con esto en tu _main.c

#include <stdio.h> int main() { char *string_to_pass = NULL; if (asprintf(&string_to_pass, "This is a test.") < 0) { printf("asprintf fail"); return -1; } PrintString(string_to_pass); return 0; }

y esto en tu main.go

package main import "C" import "fmt" //export PrintString func PrintString(cs *C.char) { s := C.GoString(cs) fmt.Println(s) } func main() {}

Usted puede hacer, para la biblioteca estática:

go build -buildmode c-archive -o mygopkg.a gcc -o main _main.c mygopkg.a -lpthread

Para la biblioteca compartida:

go build -buildmode c-shared -o mygopkg.so LD_RUN_PATH=$(pwd) gcc -o main _main.c mygopkg.so -lpthread

( LD_RUN_PATH está aquí para hacer que el vinculador busque la biblioteca compartida en el mismo directorio que está creando).

Consulte el documento de diseño de modos de ejecución Go para obtener más información.