php小編百草在寫程式碼時,常常會遇到一些問題和挑戰。其中一個常見的問題是在使用cgo編譯時遇到錯誤訊息"無法用cgo編譯"。這個問題可能由於各種原因引起,例如缺乏依賴函式庫、環境配置不正確等。解決這個問題需要仔細檢查程式碼和環境,並根據具體情況進行相應的調整和修復。在本文中,我們將分享一些解決這個問題的方法和技巧,幫助大家克服這個困擾。
您使用的 go 版本(go 版本)?
$ go version go version go1.20.2 linux/amd64
專案結構:
directory structure -- example --> main.go -->lib lib.c lib.h
main.go
package main // #include "lib/lib.h" // #include <stdio.h> // #include <stdlib.h> import "c" import ( "fmt" "unsafe" ) func main() { cstrin := c.cstring("welcome") s1 := c.struct_s1{b: cstrin, a: 100} c.f32_123(&s1) cs := c.gostring(s1.b) fmt.println(cs) fmt.println(s1) c.free(unsafe.pointer(cstrin)) }
lib/lib.c
#include <stdlib.h> #include <stdio.h> void printc(char *str, int *t) { str = "test"; printf("%d\n", *t); *t = 30; printf("%s\n", str); } void f32_123(struct s1 *s) { printf("%s\n", s->b); s->a = 10; s->b = "hello123"; printf("%d\n", s->a); printf("%s\n", s->b); }
lib/lib.h
struct s1 { int a; char *b; }; void printc(char *str, int *t); void f32_123(struct s1 *s);
編譯時出錯
/usr/local/go/pkg/tool/linux_amd64/link: running gcc failed: exit status 1 /usr/bin/ld: /tmp/go-link-3024881602/000001.o: in function _cgo_cf24297edd23_Cfunc_f32_123': /tmp/go-build/cgo-gcc-prolog:49: undefined reference to f32_123' collect2: error: ld returned 1 exit status
我期望程式碼能夠成功編譯,但不知怎的卻沒有。如果我正確閱讀了文檔,那麼我必須將 lib.c
和 lib.h
與 main.go
文件保存在同一目錄中。但我不確定這是否可以實現,或者我做錯了什麼。
如果我將所有檔案保存在同一目錄範例中,則編譯成功。
如果我將 lib.c
和 lib.h
保留到子目錄中,則編譯失敗
如果我從main.go 中刪除一個函數f32_123
,那麼編譯也會成功,這很奇怪,這就是打開此錯誤的原因,以更好地理解為什麼在lib.h
時編譯不會出現printc 函式問題且lib.c
位於子目錄。
首先,@jimb 不久前給了這個已接受的答案:https://www.php.cn/link/50c57f7019bb52cfbebdfe5bdc42b422 a> 表示在子目錄中建構物件或函式庫不是go build
可以做的事情。
有鑑於此,假設您具有以下結構:
lib/ lib/lib.c lib/lib.h main.go
以下是一些更簡單的文件,可以讓事情變得清晰:
/* lib/lib.h */ struct foo { int x; }; void show(struct foo *arg);
/* lib/lib.c */ #include <stdio.h> #include "lib.h" void show(struct foo *arg) { printf("[%d]\n", arg->x); }
因此,如果您有這樣的 main.go
,則可以從 go build main.go
建立所有內容:
package main // #cgo cflags: -i${srcdir}/lib // #include "lib.c" import "c" func main() { x := c.struct_foo{ x: 42 } c.show(&x) }
之所以有效,是因為我們實際上 #include
函式庫的「c」原始碼(隱含導入 lib/lib.h
檔案)。
但是,對於更複雜的函式庫,您可能需要將它們建置為單獨的、更正常的 c 工具鏈,預先建置步驟:
$ cd lib $ cc -c lib.c $ ar cr libx.a lib.o $ cd ..
然後使用不同的go檔:main2.go
:
package main // #cgo CFLAGS: -I${SRCDIR}/lib // #cgo LDFLAGS: -L${SRCDIR}/lib -lx // #include "lib.h" import "C" func main() { x := C.struct_foo{ x: 42 } C.show(&x) }
以上是無法用cgo編譯的詳細內容。更多資訊請關注PHP中文網其他相關文章!