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>
これGCCGO の正しいシグネチャとシンボル名を使用して PrintString 関数を宣言します。
コンパイル
Go オブジェクト ファイルを使用して C プログラムをコンパイルするには、-o を指定して gccgo を使用します。出力実行可能ファイルを指定するオプション:
gccgo -o main c_caller.c printString.o -Wall -Werror -march=native
コンパイル エラーへの対処
元の質問で言及されている最初のコンパイル エラーは、GCCGO が Go で main 関数を期待していることを示しています。ファイル。ただし、C プログラムにリンクする場合は必要ありません。この問題を解決するには、次のことを確認してください:
追加オプション
ライブラリ参照の欠落に関連するリンカー エラーに対処するには、次のオプションを試してください:
Go 1.5 の例 (2015 年 8 月)
Go 1.5 では、ゴーツール。このメソッドはプロセスを大幅に簡素化します:
_main.c
<code class="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; }</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>
静的ライブラリとしてのビルド:
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
以上がGCCGO を使用して C プログラムから Go 関数を呼び出すにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。