C和Go相互調用

aiat5431 6年前發布 | 18K 次閱讀 Cgo Google Go/Golang開發

C可以調用Go,并且Go可以調用C, 如果更進一步呢, C-->Go-->C 或者 Go-->C-->Go 的調用如何實現?

本文通過兩個簡單的例子幫助你了解這兩種復雜的調用關系。本文不涉及兩者之間的復雜的數據轉換,官方文章 C? Go? Cgo!wiki/cgocmd/cgo 有一些介紹。

Go-->C-->Go

Go程序調用C實現的函數,然后C實現的函數又調用Go實現的函數。

1、首先,我們新建一個 hello.go 的文件:

hello.go

package main

import "C"
import "fmt"

//export HelloFromGo
func HelloFromGo() {
 fmt.Printf("Hello from Go!\n")
}

它定義了一個 HelloFromGo 函數,注意這個函數是一個純的Go函數,我們定義它的輸出符號為 HelloFromGo 。

2、接著我們新建一個 hello.c 的文件:

hello.c

#include <stdio.h>
#include "_cgo_export.h"

int helloFromC() {
 printf("Hi from C\n");
 //call Go function
 HelloFromGo();
 return 0;
}

這個c文件定義了一個C函數 helloFromC ,內部它會調用我們剛才定義的 HelloFromGo 函數。

這樣,我們實現了 C 調用 Go : C-->Go ,下面我們再實現Go調用C。

3、最后新建一個 main.go 文件:

main.go

package main

/*
extern int helloFromC();
*/
import "C"

func main() {
 //call c function
 C.helloFromC()
}

它調用第二步實現的C函數 helloFromC 。

運行測試一下:

$ go run .
Hi from C
Hello from Go!

可以看到,期望的函數調用正常的運行。第一行是C函數的輸出,第二行是Go函數的輸出。

C-->Go-->C

第二個例子演示了C程序調用Go實現的函數,然后Go實現的函數又調用C實現的函數。

1、首先新建一個 hello.c 文件:

hello.c

#include <stdio.h>

int helloFromC() {
 printf("Hi from C\n");
 return 0;
}

它定義了一個純C實現的函數。

2、接著新建一個 hello.go 文件:

// go build -o hello.so -buildmode=c-shared .
package main

/*
extern int helloFromC();
*/
import "C"

import "fmt"

//export HelloFromGo
func HelloFromGo() {
    fmt.Printf("Hello from Go!\n")
    C.helloFromC()
}

func main() {

}

它實現了一個Go函數 HelloFromGo ,內部實現調用了C實現的函數 helloFromC ,這樣我們就實現了 Go-->C 。

注意包名設置為 package main ,并且增加一個空的 main 函數。

運行 go build -o hello.so -buildmode=c-shared . 生成一個C可以調用的庫,這調命令執行完后會生成 hello.so 文件和 hello.h 文件。

3、最后新建一個文件夾,隨便起個名字,比如 main

將剛才生成的 hello.so 文件和 hello.h 文件復制到 main 文件夾,并在 main 文件夾中新建一個文件 main.c :

main.c

#include <stdio.h>
#include "hello.h"

int main() {
 printf("use hello lib from C:\n");

 HelloFromGo();

 return 0;
}

運行 gcc -o main main.c hello.so 生成可執行文件 main , 運行 main :

$ ./main
use hello lib from C:
Hello from Go!
Hi from C

第一行輸出來自 main.c ,第二行來自Go函數,第三行來自 hello.c 中的C函數,這樣我們就實現了 C-->Go--C 的復雜調用。

參考文檔

  1. https://medium.com/using-go-in-mobile-apps/using-go-in-mobile-apps-part-1-calling-go-functions-from-c-be1ecf7dfbc6
  2. https://github.com/vladimirvivien/go-cshared-examples
  3. http://golang.org/cmd/cgo
  4. https://gist.github.com/zchee/b9c99695463d8902cd33
  5. https://medium.com/@liamkelly17/working-with-packed-c-structs-in-cgo-224a0a3b708b

 

來自:https://colobu.com/2018/08/28/c-and-go-calling-interaction/

 

 本文由用戶 aiat5431 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!