下載本文檔
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第詳解如何在Go語言中調(diào)用C源代碼目錄開坑說明內(nèi)嵌形式外置的C代碼1.構(gòu)建libauth.a靜態(tài)庫2.對main.go稍加修改3.編譯
開坑說明
最近在編寫客戶端程序或與其他部門做功能集成時多次碰到了跨語言的sdk集成,雖說方案很多諸如rpc啊,管道啊,文件io啊,unixsocket啊之類的不要太多,但最完美的基礎(chǔ)方式還是讓程序與sdk結(jié)合到一起(個人觀點,不喜勿噴),順便研究了下在go調(diào)用標準c接口的種種方法與坑,內(nèi)容不少,有空便慢慢更新了。
內(nèi)嵌形式
先讓我們來看一個最簡單的cgo實例
packagemain
//#includestdio.h
import"C"
funcmain(){
C.puts(C.CString("HelloWorld"))
輸出
HelloWorld
通過C包調(diào)用了c中常見的puts函數(shù)同時傳入通過C.Cstring把go中string轉(zhuǎn)化為的cstring(相當于char*)。其實C這個并不是一個包,而是通過importC語句啟用了go編譯器cgo相關(guān)的功能讓gcc也參與到了編譯中。這種方式通過緊貼在importC語句上面的注釋中編寫c代碼并在后續(xù)代碼中使用C對象調(diào)用。當然也可以通過這種方式調(diào)用自定義的c函數(shù)。
packagemain
import"C"
/*#includestdio.h
voidsay_hello_with_name(char*name){
printf("hello%s\n",name);
import"C"
funcmain(){
C.say_hello_with_name(C.CString("oscar"))
}
輸出
hellooscar
外置的C代碼
內(nèi)置的C代碼固然很方便,但用到cgo大多數(shù)的使用場景是我有一個需要復(fù)用的c代碼庫,像是c++的stl庫亦或者是linuxc中的什么已經(jīng)封裝好的第三方依賴。這些時候便需要外置一些c的文件.h.c.cpp之類與.go文件混編。先看一個最簡單的例子(調(diào)用linux的系統(tǒng)賬戶認證)。
//auth.h
intauth(char*user,char*passwd);
//auth.c
#includeshadow.h
#includestdio.h
#includeunistd.h
intauth(char*user,char*passwd){
char*obtpwd;
structspwd*spasswd;
spasswd=getspnam(user);
obtpwd=crypt(passwd,spasswd-sp_pwdp);
if(strcmp(spasswd-sp_pwdp,obtpwd)==0)
return0;
elsereturn1;
}
//main.go
packagemain
#cgoLDFLAGS:-lcrypt
#include"auth.h"
import"C"
import"fmt"
funcmain(){
varusername,passwordstring
fmt.Println("Pleaseenteryourusernameandpassword:")
_,_=fmt.Scanln(username,password)
rst:=C.auth(C.CString(username),C.CString(password))
fmt.Println(rst)
}
保證上述三個文件在同一個go工程目錄下運行g(shù)obuild-omain構(gòu)建工程。#cgoLDFLAGS:-lcrypt這個一行是cgo給gcc的編譯參數(shù),相關(guān)的編譯參數(shù)與連接參數(shù)有空了在后面的文章里說明,-lcrypt表示編譯時需要去連接libcrypt這個庫。
注意,這種cgo混編的方式個人是不建議的,cgo對外置c代碼片構(gòu)建支持非常差,我無法在cgo中通過編譯參數(shù)指定c代碼片的搜索路徑(頭文件倒是沒啥問題),這也就意味著當項目被調(diào)用的c代碼片都得在項目根目錄下,這可太糟糕了。個人覺得如果有大量的外部依賴c語言的庫請分開編譯,c庫使用gcc編譯成靜態(tài)或動態(tài)庫在讓go在編譯時連接為好,寫個makefile分開分步編譯也不是什么麻煩事,還是上面的例子,讓我們把編譯的過程稍加修改。
1.構(gòu)建libauth.a靜態(tài)庫
gcc-c-oauth.o-lcryptauth.c
arrcslibauth.aauth.o
得到libauth.a
2.對main.go稍加修改
packagemain
#cgoCFLAGS:-I./
#cgoLDFLAGS:-L.-lauth-lcrypt
#include"auth.h"
import"C"
import"fmt"
funcmain(){
varusername,passwordstring
fmt.Println("Pleaseenteryourusernameandpassword:")
_,_=fmt.Scanln(username,password)
rst:=C.auth(C.CString(username),C.CString(password))
fmt.Println(rst)
此處修改主要是新增了libauth.a靜態(tài)庫的鏈接參數(shù)
3.編譯
gobuild-omainmain.go
可以把上述的步驟整下寫個簡單的makefile
.PHONY:all
all:main
libauth.a:auth.c
gcc-c-oauth.o-lcryptauth.c
arr
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 基于核心素養(yǎng)的初中歷史大單元概念對比復(fù)習教學設(shè)計-以統(tǒng)編版九年級《世界歷史》上冊為例
- 彩色塑膠地面施工方案范本
- Unit5FirstAidReadingandThinking課件高中英語人教版選擇性()-1
- 七年級英語起始單元《Hello!》大概念統(tǒng)領(lǐng)下的素養(yǎng)導(dǎo)向教學設(shè)計
- 鍋爐安裝施工方案
- 建筑工程技術(shù)學科高職二年級《框架工程二次結(jié)構(gòu)砌筑施工方案》教學設(shè)計
- 基于大概念的單元教學:《分式的乘除(第一課時)》教學設(shè)計-以蘇科版數(shù)學八年級下冊為例
- 探秘中華水系共筑人水和諧-八年級地理上冊“中國的河流與湖泊”單元教學設(shè)計
- 墻面刷噴涂料施工方案
- 2024年秋季新西師大版一年級上冊數(shù)學課件 第三單元 認識立體圖形 練習八
- 湖南省婁底市新化縣2024-2025學年高一上學期期末考試生物試題(解析版)
- GB/T 45629.1-2025信息技術(shù)數(shù)據(jù)中心設(shè)備和基礎(chǔ)設(shè)施第1部分:通用概念
- 2025年中考歷史開卷考查范圍重大考點全突破(完整版)
- 學術(shù)誠信與學術(shù)規(guī)范研究-深度研究
- 《ETF相關(guān)知識培訓(xùn)》課件
- (一模)烏魯木齊地區(qū)2025年高三年級第一次質(zhì)量英語試卷(含答案)
- 2025年云南省普洱市事業(yè)單位招聘考試(833人)高頻重點提升(共500題)附帶答案詳解
- DB15-T 3677-2024 大興安嶺林區(qū)白樺樹汁采集技術(shù)規(guī)程
- 2024年《13464電腦動畫》自考復(fù)習題庫(含答案)
- 義務(wù)教育階段學生語文核心素養(yǎng)培養(yǎng)的思考與實踐
- 綜合利用1噸APT渣項目研究報告樣本
評論
0/150
提交評論