首頁 > 後端開發 > Golang > 無法用cgo編譯

無法用cgo編譯

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
發布: 2024-02-09 16:21:09
轉載
1348 人瀏覽過

無法用cgo編譯

php小編百草在寫程式碼時,常常會遇到一些問題和挑戰。其中一個常見的問題是在使用cgo編譯時遇到錯誤訊息"無法用cgo編譯"。這個問題可能由於各種原因引起,例如缺乏依賴函式庫、環境配置不正確等。解決這個問題需要仔細檢查程式碼和環境,並根據具體情況進行相應的調整和修復。在本文中,我們將分享一些解決這個問題的方法和技巧,幫助大家克服這個困擾。

問題內容

您使用的 go 版本(go 版本)?

1

2

$ go version

go version go1.20.2 linux/amd64

登入後複製

專案結構:

1

2

3

4

5

directory structure --

example --> main.go

        -->lib

            lib.c

            lib.h

登入後複製

main.go

#

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

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

#

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

#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

#

1

2

3

4

5

6

7

struct s1 {

    int a;

    char *b;

};

 

void printc(char *str, int *t);

void f32_123(struct s1 *s);

登入後複製

編譯時出錯

1

2

3

/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.clib.hmain.go 文件保存在同一目錄中。但我不確定這是否可以實現,或者我做錯了什麼。

  • 如果我將所有檔案保存在同一目錄範例中,則編譯成功。

  • 如果我將 lib.clib.h 保留到子目錄中,則編譯失敗

  • 如果我從main.go 中刪除一個函數f32_123 ,那麼編譯也會成功,這很奇怪,這就是打開此錯誤的原因,以更好地理解為什麼在lib.h 時編譯不會出現printc 函式問題且lib.c 位於子目錄。

解決方法

首先,@jimb 不久前給了這個已接受的答案:https://www.php.cn/link/50c57f7019bb52cfbebdfe5bdc42b422 表示在子目錄中建構物件或函式庫不是go build 可以做的事情。

有鑑於此,假設您具有以下結構:

1

2

3

4

lib/

lib/lib.c

lib/lib.h

main.go

登入後複製

以下是一些更簡單的文件,可以讓事情變得清晰:

1

2

3

4

5

/* lib/lib.h */

struct foo {

    int x;

};

void show(struct foo *arg);

登入後複製

1

2

3

4

5

6

/* 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 建立所有內容:

1

2

3

4

5

6

7

8

9

10

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 工具鏈,預先建置步驟:

1

2

3

4

$ cd lib

$ cc -c lib.c

$ ar cr libx.a lib.o

$ cd ..

登入後複製

然後使用不同的go檔:main2.go

1

2

3

4

5

6

7

8

9

10

11

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中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板