1. 程式人生 > >go 與c的 相互呼叫

go 與c的 相互呼叫

Golang與C的關係非常密切,下面主要介紹在Golang中使用C。

一. Golang中嵌入C程式碼
  1 package main                                                                                                                    
  2  
  3 //#include <stdio.h>
  4 //#include <stdlib.h>
  5 /*
  6 void Hello(char *str) {
  7     printf("%s\n", str);
  8 }
  9 */
 10 import "C" //假設把C當成包,其實有點類似C++的名字空間
 11 import "unsafe" //C指標的使用,在C程式碼中申請的空間,GC垃圾回收機制不會管理,所以需要自己手動free申請的空間
 12  
 13 func main() {
 14     s := "Hello Cgo"
 15     cs := C.CString(s)
 16     C.Hello(cs)
 17     C.free(unsafe.Pointer(cs))
 18 }

3,4行的註釋也可以寫/* */形式 
第4行與第5行之間不能有空行,同樣第9行與第10行之間也不 
能有行,否則編譯時cgo會報錯:

[email protected]:~/mygo/src/myC/tmp$ go run goc.go
# command-line-arguments
could not determine kind of name for C.Hello
could not determine kind of name for C.free

Golang中呼叫C的動態庫so
C庫源程式程式碼:

  1 //foo.c                                                                                                                         
  2 #include <stdio.h>
  3  
  4 int Num = 8;
  5  
  6 void foo(){
  7     printf("I dont have new line.");
  8     printf("I have new line\n");
  9     printf("I have return\r");
 10     printf("I have return and new line\r\n");
 11 }

  1 //foo.h                                                                                                                         
  2 #ifndef __FOO_H
  3 #define __FOO_H
  4  
  5 #ifdef __cplusplus
  6 extern "C" {
  7 #endif
  8  
  9 extern int Num;
 10 extern void foo();
 11  
 12 #ifdef __cplusplus
 13 }
 14 #endif
 15  
 16 #endif

Go呼叫C庫的程式碼:

  1 package main                                                                                                                    
  2  
  3 /*
  4 #cgo CFLAGS: -I.
  5 #cgo LDFLAGS: -L. -lfoo
  6 #include <stdio.h>
  7 #include <stdlib.h>
  8 #include "foo.h"
  9 */
 10 import "C"
 11 import "unsafe"
 12 import "fmt"
 13  
 14 func Prin(s string) {
 15     cs := C.CString(s)
 16     defer C.free(unsafe.Pointer(cs))
 17     C.fputs(cs, (*C.FILE)(C.stdout))
 18     //C.free(unsafe.Pointer(cs))
 19     C.fflush((*C.FILE)(C.stdout))
 20 }
 21  
 22 func main() {
 23     fmt.Println("vim-go")
 24     fmt.Printf("rannum:%x\n", C.random())
 25     Prin("Hello CC")
 26     fmt.Println(C.Num)
 27     C.foo()
 28 }

注意import “C”這行與第9行之間也不能有空格,原因同上編譯會報錯。 
go與庫、標頭檔案的目錄結構,以及編譯:

[email protected]:~/mygo/src/myC/sotest$go build cc.go //編譯之後產生cc
[email protected]:~/mygo/src/myC/sotest$ ls
cc  cc.go  foo.h  libfoo.so
[email protected]:~/mygo/src/myC/sotest$ export LD_LIBRARY_PATH=./
[email protected]:~/mygo/src/myC/sotest$ ./cc
vim-go
rannum:6b8b4567
Hello CC8
I dont have new line.I have new line
I have return and new line

如果c庫的程式改為下面這樣:

  1 //foo.c                                                                                                                         
  2 #include <stdio.h>
  3  
  4 int Num = 8;
  5  
  6 void foo(){
  7     printf("I dont have new line.");
  8     //printf("I have new line\n");
  9     //printf("I have return\r");
 10     //printf("I have return and new line\r\n");
 11 }

此時,go中呼叫foo時沒有任何反應,即不會輸出,不會輸出的原因是printf後面沒有加換行符,但是如果加了8,9,10這些測試行後,第7行也會顯示,原因是第10行最後有一個換行符,這個應該是向stdout輸出時,字元流是放在buffer中,如果沒有換行,buffer中的資料不會立即輸出。在go呼叫C的測試程式中有寫了一個測試小函式用來測試stdout,驗證了沒有fflush,stdout上不會顯示輸出資訊。但平時在寫C程式的時候,似乎沒有這樣的問題,這個是因為C的執行環境自動做了fflush的動作,這個可能是Golang的不足,也許golan表g認為這樣做更好。這只是個人的分析,如有分析不對的地方,請跟貼,謝謝。

Golang呼叫C的靜態庫a
所有源程式與動庫演示程式碼類似,只是編譯C庫時,是用的靜態編譯,如下所示:

[email protected]:~/mygo/src/myC$ ls
foo.c 
[email protected]:~/mygo/src/myC$ gcc -c foo.c
foo.c foo.o
[email protected]:~/mygo/src/myC$ ar -rv libfoo.a foo.o
foo.c foo.o libfoo.a

Go呼叫的程式碼與動態庫一樣,下面是目錄結構:

[email protected]:~/mygo/src/myC/atest$ ls
cc  cc.go  foo.h  libfoo.a
--------------------- 
作者:JXES 
來源:CSDN 
原文:https://blog.csdn.net/linuxandroidwince/article/details/78733366 
版權宣告:本文為博主原創文章,轉載請附上博文連結!

相關推薦

cc++相互呼叫機制分析實現

c++通常被稱為Better c,多數是因為c++程式可以很簡單的呼叫c函式,語法上基本實現相容。最常用的呼叫方式就是c++模組呼叫c實現的dll匯出函式,很簡單的用法,使用extern "C"將c標頭檔案或者函式修飾下。 本文主要涉及到在c模組中如何呼叫c++函式,或者換個名字,extern

android java c++ 相互呼叫的方法

android java 與 c++ 相互呼叫的方法 最近在寫native部分的程式碼,需要c++和java相互呼叫。記得JK之前說過他弄了一個新的方法,在寫jni的時候會自由一點,我對了一下他的程式碼,根據我的場景寫了一個出來。在這裡給自己做一點筆記吧。 Android.mk

CC++相互呼叫問題

在專案中融合C和C++有時是不可避免的,在呼叫對方的功能函式的時候,或許會出現這樣那樣的問題,但只要我的C程式碼和我的C++程式碼分別都能成功編譯,那其他就不是問題。近來在主程式是C語言,而呼叫C++功能函式的時候,C++的*.h標頭檔案都能找到,功能函式也都定義了,最重要的

go c相互呼叫

Golang與C的關係非常密切,下面主要介紹在Golang中使用C。 一. Golang中嵌入C程式碼   1 package main                                                                    

Python介面(3):Python例項淺談之三PythonC/C++相互呼叫

一、問題      Python模組和C/C++的動態庫間相互呼叫在實際的應用中會有所涉及,在此作一總結。 二、Python呼叫C/C++ 1、Python呼叫C動態連結庫         Python呼叫C庫比較簡單,不經過任何封裝打

C語言組合語言相互呼叫

在使用C語言時,要用到和組合語言的混合程式設計。若彙編程式碼較為簡潔,則可使用直接內嵌彙編的方法;否則要將彙編程式以檔案的形式加入到專案中,按照ATPCS(ARM/Thumb過程呼叫標準,ARM/Thumb Procedure Call Standard)的規定與C程

Unity3D 預備知識:C#Lua相互呼叫

public class CSharpLuaTest : MonoBehaviour { private LuaState luaState = new LuaState(); // 建立lua虛擬機器 void Start () { //

pythonC/C++相互呼叫

C/C++呼叫python python作為一種膠水語言可以很靈活的嵌入到C++和java等主語言裡面進行互操作實現擴充套件功能。 方法1:使用python提供的C介面(基礎) 使用python提供給C/C++的API,將python程式程式設計文字形式的動態連結庫,可

1、在C#Lua相互呼叫

一、利用LuaInterface呼叫lua程式碼 1、下載luainterface,這裡用的luainterface-1.5.3版本。 2、新增 LuaInterface.dll的引用。 3、利用直譯器進行呼叫 using System;   using L

unity中c#Objective-C相互呼叫

前言 在unity中接入sdk或者定製一些功能時,需要呼叫系統介面。iphone手機實際操作中,也就是Unity與iOS相互呼叫。我們在Unity中使用c#,iOS中使用Objective-C(以下稱為oc)。 下面介紹他們如何相互呼叫。 c# 呼叫

OCswift相互呼叫

OC與swift相互呼叫 一、OC呼叫swift檔案 二、swift呼叫OC檔案 三、注意和總結 新增: 四、自定義橋接檔案  一、OC呼叫swift檔案   在OC專案中建立一個swift檔案的時候,Xcode 會提示 需要建立一個橋接檔案,點

swift專案中 OCswift相互呼叫

swift呼叫oc的方法: 1、橋接檔案,一般是swift工程,在建立一個oc檔案時,系統自動新增(不用改名,直接預設即可) 2、將需要引用的oc檔案 .h標頭檔案 新增到橋接類中。 具體方法可以參考我的這篇部落格,裡面進行了詳細講解 oc呼叫swift 1、首先設定一

vb netc 相互轉換工具

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

C++:函式的過載、inline函式、C/C++相互呼叫

一、過載(overloading) :函式名字相同,而引數不同。返回型別可以相同也可以不同。      若有題目為:實現兩個數相加,一般我們都會想到如下程式碼: int Sum(int a,int b) { return a

WebBrowser(IE) JS 相互呼叫

在開發中我們經常將WebBrowser控制元件嵌入Winform 程式來瀏覽網頁,既然是網頁那麼少不了JS。下面就讓我們來說說他們兩之間的相互呼叫。 在C#封裝的瀏覽器核心中,Chromium 核心封裝有Xilium.Cefglue、Cefsharp,Webkit 核心封裝

C# 用XiliumCefGlue做瀏覽器,JS和C#相互呼叫

目錄: XiliumCefGlue初始化,最精簡Demo 1.解壓壓縮包得到下列檔案。選擇需要的檔案複製到自己工程【pdb為除錯生成檔案不需要】,之後將【Xilium.CefGlue】和【Xilium.CefGlue.WindowsForm

FlexJS相互呼叫

(1):在Flex中有這麼一個類:ExternalInterface.在這個類中它給我們:call和addCallback Flex中As呼叫Js的方法是:      1、匯入包 (import flash.external.ExternalInterface;)  

WebView使用詳解(一)——NativeJS相互呼叫(附JadX反編譯)

前言:念念不忘,必有迴響,永遠堅持你所堅持的!一直在用WebView,還沒有系統的總結過它的用法,下面就係統的總結下,分享給大家一、基本用法1、載入線上URL[java] view plain copy print?void loadUrl(String url

JAVA和C/C++相互呼叫

JNIJAVA和C/C++相互呼叫 1、JAVA可以通過JNI呼叫C/C++函式 2、C/C++也可以通過JNI相關函式,來呼叫JAVA。並且可以訪問到JAVA類中所有成員變數和成員函式。 要實現C/

iOS開發ocjs相互呼叫的方式方法

文章主要是介紹oc如何呼叫js 以及js的程式碼呼叫oc的方法  先上程式碼後做解釋 //oc的.m 的程式碼 //ps接下來有js的程式碼一併解析,最後會附上demo //  ViewController.m //  JSAndOC // //  Create