首頁 >後端開發 >Golang >如何使用 GCCGO 從我的 C 程式呼叫 Go 函數?

如何使用 GCCGO 從我的 C 程式呼叫 Go 函數?

DDD
DDD原創
2024-10-26 16:21:02514瀏覽

How can I Call Go Functions from My C Program Using GCCGO?

使用GCCGO 從C 程式呼叫Go 函數

簡介

整合Go 程式碼在現像有的C 專案中,必須從Go 檔案建立一個目標檔案(.o),並將其合併到C 專案的存檔(.a) 檔案中。本文詳細說明如何使用 GCCGO 來完成此任務。

建立Go 物件檔案

要從Go 文件建立物件文件,請使用gccgo帶有-c 選項的命令編譯檔案而不連結它:

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

-fgo-prefix 選項指定從Go 檔案匯出的符號的前綴。

將Go 函數連結到C 程式

要將Go 目標檔案連結到C 程序,請在C 程式碼中使用extern 宣告和__asm__ 關鍵字:

<code class="c">#include <stdio.h>

extern int PrintString(char*) __asm__ ("print.main.PrintString");</code>

This使用GCCGO 的正確簽章和符號名稱來宣告PrintString 函數。

編譯

要使用Go 目標檔編譯C 程序,請使用gccgo 和-o指定輸出執行檔的選項:

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

解決編譯錯誤

原始問題中提到的初始編譯錯誤表明GCCGO 需要Go 中的main 函數檔。然而,當連結到 C 程式時,這不是必需的。要解決此問題,請確保:

  • Go 檔案不包含 main 函數。
  • C 程式定義了自己的 main 函數。

其他選項

要解決與缺少庫引用相關的連結器錯誤,請嘗試以下選項:

  • - -static-libgo:使用靜態版本
  • -static:連結靜態庫而不是共享庫。
  • -Wl,-R,/path/to/libgo.so's_folder:指定路徑包含 libgo.so 的資料夾。

Go 1.5 的範例(2015 年 8 月)

Go 1.5 引入了直接使用建置 C 相容程式庫的功能去工具。此方法顯著簡化了流程:

_main.c

<code class="c">#include <stdio.h>

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

    PrintString(string_to_pass);
    return 0;
}</code>

main.go

<code class="go">package main

import "C"
import "fmt"

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

func main() {}</code>

main.go

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

main.go
go build -buildmode c-shared -o mygopkg.so
LD_RUN_PATH=$(pwd) gcc -o main _main.c mygopkg.so -lpthread
建置為靜態函式庫:建置為共用程式庫:

以上是如何使用 GCCGO 從我的 C 程式呼叫 Go 函數?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn