<code id="ymukc"><xmp id="ymukc">

C和Go相互調用

Cgo   2018-08-29 08:58:46 發布
您的評價:
     
0.0
收藏     0收藏
文件夾
標簽
(多個標簽用逗號分隔)

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/

 

六合特码资料
<code id="ymukc"><xmp id="ymukc">
<code id="ymukc"><xmp id="ymukc">

擴展閱讀

使用Go語言開發iOS應用(Swift版)
不用 SWIG,Go 使用 C++ 代碼的方式
Go開源框架,類庫和軟件集合
Go語言框架、開發庫和軟件及資源大全
非常棒的Go語言框架,庫和軟件集合:Awesome Go

為您推薦

嵌入式設備web服務器比較
PostgreSQL vs. MS SQL Server
hackathon-starter - A boilerplate for Node.js web applications
選擇一個 Python Web 框架:Django vs Flask vs Pyramid
各種Java加密算法

更多

Cgo
Google Go/Golang開發