亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在現有 C 項目中使用 Go 代碼

在現有 C 項目中使用 Go 代碼

Go
catspeake 2021-11-01 16:42:34
自從 Go 1.5 出來后,我開始重新審視如何將它集成到我現有的項目中。該項目的代碼庫完全用 C 編寫,用于對硬件和其他有趣的東西進行低級訪問。但是,一些更高層次的東西很乏味,我想開始用更高層次的語言(Go)編寫它們有什么辦法可以從 C 程序中調用 Go 代碼嗎?我安裝了 Go 1.5,它添加了-buildmode=c-archive(https://golang.org/s/execmodes),我正在嘗試開始工作。但是,我似乎無法讓 Go 生成適當的頭文件以允許我的項目實際編譯。當我生成存檔時,我在導出的符號中看到了該函數(使用 objdump),但沒有包含 gcc 的頭文件會抱怨該函數不存在(如預期的那樣)我對 Go 還很陌生——但是,我喜歡這門語言并想使用它。有沒有什么慣用的方式(“慣用的”在圍棋世界中被大量使用,我看到......)來讓它相互很好地發揮作用?我問這個問題并特別提到 Go 1.5 的原因是根據這個文檔,https://docs.google.com/document/d/1nr-TQHw_er6GOQRsF6T43GGhFDelrAP0NqSS_00RgZQ/edit?pli= 1# heading= h.1gw5ytjfcoke 添加了 Go 1.5支持非 Go 程序調用 Go 代碼。具體來說,在“Go 代碼鏈接到非 Go 程序并從中調用”一節中提到
查看完整描述

1 回答

?
慕婉清6462132

TA貢獻1804條經驗 獲得超2個贊

要構建可從 C 調用的存檔,您需要將它們標記為導出的 CGo 符號。

例如,如果我創建一個foo.go包含以下內容的文件:


package main


import (

    "C"

    "fmt"

)


//export PrintInt

func PrintInt(x int) {

    fmt.Println(x)

}


func main() {}

需要注意的重要事項是:


需要調用包 main

你需要有一個main函數,雖然它可以是空的。

您需要導入包 C

您需要特殊//export注釋來標記您希望從 C 中調用的函數。

我可以使用以下命令將其編譯為 C 可調用靜態庫:


go build -buildmode=c-archive foo.go

結果將是一個存檔foo.a和一個標題foo.h。在標題中,我們得到以下內容(刪除不相關的部分):


...

typedef long long GoInt64;

...

typedef GoInt64 GoInt;

...

extern void PrintInt(GoInt p0);

...

所以這足以調用導出的函數。我們可以編寫一個簡單的 C 程序,像這樣調用它:


#include "foo.h"


int main(int argc, char **argv) {

    PrintInt(42);

    return 0;

}

我們可以使用如下命令編譯它:


gcc -pthread foo.c foo.a -o foo

該-pthread選項是必需的,因為 Go 運行時使用線程。當我運行生成的可執行文件時,它會打印42.


查看完整回答
反對 回復 2021-11-01
  • 1 回答
  • 0 關注
  • 146 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號