[英]Using Go on existing C project
我有一個完全用C語言編寫的程序,它使用多個對象(.o)
文件。 這些文件都打包在一個存檔文件(.a)
中,而后者又在程序主(.c)
文件的編譯時使用。
我想在Go中為這個項目寫一個新文件。 我的想法是編寫這個.go
文件,然后從中創建一個對象(.o)
文件。 之后,我想將此對象文件放在已經提到的存檔(.a)
文件中。
這基本上意味着我想從C程序調用Go函數 。 我已經讀過這個問題了 ,雖然它向我展示了我想要的東西可能是通過GCCGO,但它並不是100%清楚如何做到這一點。
即使使用最基本的測試,我也會在鏈接階段遇到錯誤。 更具體地說,這是一個基本的例子:
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;
}
編譯
為了編譯Go文件,我使用了以下命令:
gccgo -c printString.go -o printString.o -fgo-prefix=print -Wall -Werror -march=native
為了編譯整個東西,我使用了這個命令:
gccgo -o main c_caller.c printString.o -Wall -Werror -march=native
我得到的回復信息是:
/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
這意味着GCCGO期望Go文件中的主要功能而不是C文件。
在第二個命令上使用--static-libgo
, -static
和--static-libgo
, -Wl,-R,/path/to/libgo.so's_folder
選項會產生不同的結果:
/usr/bin/ld: cannot find -lgo
collect2: error: ld returned 1 exit status
這沒有任何意義,因為我有LD_LIBRARY_PATH環境變量正確指向libgo.so的文件夾。
我意識到我可能在這里做錯了什么,但我看不出那是什么。 接下來沒有GCCGO的例子以及它與C的交互,我唯一能找到的參考是這個頁面 ,我個人認為這還不夠。
我請你就這件事提出一些建議,謝謝你的時間。 :)
這可能不是你想要的,但是在今年8月即將發布的Go 1.5中 ,你將能夠使用go工具構建與C兼容的庫。 所以在你的_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;
}
這在你的main.go
package main
import "C"
import "fmt"
//export PrintString
func PrintString(cs *C.char) {
s := C.GoString(cs)
fmt.Println(s)
}
func main() {}
你可以為靜態庫做:
go build -buildmode c-archive -o mygopkg.a
gcc -o main _main.c mygopkg.a -lpthread
對於共享庫:
go build -buildmode c-shared -o mygopkg.so
LD_RUN_PATH=$(pwd) gcc -o main _main.c mygopkg.so -lpthread
( LD_RUN_PATH
用於使鏈接器在您正在構建的同一目錄中查找共享庫。)
有關詳細信息,請參閱Go執行模式設計文檔 。
目前沒有支持的方法來做你想要的。 Go始終需要其運行時的支持,並且其入口點始終是main
。 AFAIK,gccgo也做出了同樣的假設,並沒有提供一種輕松鏈接到其他程序的方法。
如果您想以受支持的方式執行此操作,則必須等到go1.5 +正在完成工作以從Go代碼編譯共享庫。
如果您現在真的想破解這一點,您可以使用帶有-linkmode external
的默認gc工具鏈來查看Android端口的工作原理,它會在目標文件中重命名main
並在外部調用它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.