版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
Go語言與其他語言的結(jié)合運(yùn)用Go語言從入門到精通了解Cgo了解Go語言與WebAssembly的結(jié)合運(yùn)用01CGO02SCRIPT03ASSEMBLYtarget目標(biāo)了解幾種Go語言中運(yùn)行的腳本語言目錄導(dǎo)航18.1CgoContentsCgo
直接調(diào)用C語言編寫的函數(shù)庫
Go語言最初最主要的優(yōu)勢之一可以直接利用龐大的C語言積累資源Cgo–先以類似注釋的語法加入C語言代碼package
main
/*#include
<stdio.h>#include
<stdlib.h>#include
<time.h>
//
是否初始化隨機(jī)數(shù)種子的標(biāo)志int
randomizeFlagG
=
0;
//
獲取一個隨機(jī)數(shù)int
getRandomInt(int
maxA)
{
if
(randomizeFlagG
==
0)
{
//
初始化隨機(jī)數(shù)種子
srand(time(NULL));
}
//
限制隨機(jī)數(shù)值范圍
int
rs
=
rand()%maxA;
//
為了演示,在C語言函數(shù)中輸出一下生成的隨機(jī)數(shù)
printf("%d\n",
rs);
return
rs;}
//
輸出一個字符串void
printString(char
*str)
{
printf("%s\n",
str);}
*/Cgo–然后再Go語言中調(diào)用import
"C"
import
(
"fmt"
"unsafe")
func
main()
{
//
調(diào)用C的標(biāo)準(zhǔn)庫函數(shù)puts來輸出
C.puts(C.CString("這是一個test."))
//
將Go語言字符串轉(zhuǎn)換為C語言格式的字符串
cStrT
:=
C.CString("測試字符串")
//
調(diào)用C語言中自定義的函數(shù)來輸出
C.printString(cStrT)
//
確保釋放C語言格式的字符串所占用的內(nèi)存空間
defer
C.free(unsafe.Pointer(cStrT))
//
調(diào)用C語言中定義的函數(shù)獲取一個隨機(jī)數(shù)
rs
:=
C.getRandomInt(20)
//
輸出該隨機(jī)數(shù)及其在Go語言中的類型
fmt.Printf("%T,
%#v\n",
rs,
rs)}直接引用C語言文件package
main
/*#include
"test.h"*/import
"C"
import
"tools"
func
main()
{
C.show3Times(C.CString(string(tools.ConvertBytesFromUTF8ToGB18030([]byte("[時間]")))))}C語言代碼在test.c中,頭文件是test.hGo語言中編寫函數(shù)供C語言調(diào)用package
main
import
(
"C"
"fmt"
"/topxeq/txtk")
//export
printInGofunc
printInGo(value
string)
{
fmt.Println(value)}
//export
getRandomIntfunc
getRandomInt(maxA
int)
int
{
return
txtk.GetRandomIntLessThan(maxA)}
//
必須要有一個主函數(shù)main,可以沒有內(nèi)容func
main()
{}gobuild-buildmode=c-shared-ocgo3.dllcgo3.go將生成cgo3.h和cgo3.dllC語言中調(diào)用Go函數(shù)的寫法#include
"cgo3.h"
#include
<stdio.h>#include
<string.h>
int
main(){
char
strT[]
=
"隨機(jī)數(shù)";
int
lenT
=
strlen(strT);
GoString
goStrT
=
{strT,
lenT};
printInGo(goStrT);
GoInt
randomT
=
getRandomInt(100);
printf("%s:
%lld\n",
strT,
randomT);
return
0;}Cgo的局限大多數(shù)數(shù)據(jù)類型在Go語言和C語言之間要做轉(zhuǎn)換才能正確使用一些數(shù)據(jù)類型存在差異,稍不注意容易產(chǎn)生混淆,例如C語言中的int一般相當(dāng)于Go語言中的int32,而longlong才相當(dāng)于Go語言中的int64
cgo中不能支持C語言中printf這類函數(shù)中使用的可變個數(shù)的參數(shù)形式,無法直接在Go語言中調(diào)用C語言中的printf這一類的函數(shù)。目錄導(dǎo)航18.2Go語言中運(yùn)行其他腳本語言Contentstengo腳本語言(/d5/tengo)sum
:=
0
//
變量初始化和賦值語句與Go語言基本一致
a
:=
0
//
循環(huán)語句也很像Go語言中的//
變量maxA是將從Go語言中傳遞進(jìn)來的for
a
<
maxA
{
sum
+=
a
a
++}
//
也有printf等內(nèi)置函數(shù)//
times函數(shù)是在Go語言中定義的//
這里演示了在腳本語言中調(diào)用Go語言中代碼的能力printf("%d\n",
times(2,
3,
4))創(chuàng)建tengo虛擬機(jī)并執(zhí)行腳本//
新建一個腳本運(yùn)行的虛擬機(jī)//
一般會編譯為字節(jié)碼準(zhǔn)備運(yùn)行s
:=
script.New([]byte(codeT))
//
向腳本執(zhí)行環(huán)境(虛擬機(jī)VM)中傳入變量maxA_
=
s.Add("maxA",
20)
//傳入準(zhǔn)備在虛擬機(jī)中執(zhí)行的Go語言編寫的函數(shù)times_
=
s.Add("times",
times)
//
執(zhí)行腳本c,
err
:=
s.Run()if
err
!=
nil
{
panic(err)}
//
獲取返回值(腳本中的sum變量)sumT
:=
c.Get("sum")
//
轉(zhuǎn)換類型后輸出fmt.Println(sumT.Int())實現(xiàn)JavaScript虛擬機(jī)的/robertkrimen/otto包vmT
:=
otto.New()//
新建Javascript虛擬機(jī)vmT.Set("a",
18)//
設(shè)置虛擬機(jī)中的變量a為數(shù)字18vmT.Set("text1",
"[計算結(jié)果]
")//
設(shè)置虛擬機(jī)中的變量text1為字符串
//
設(shè)置供虛擬中Javascript代碼調(diào)用的Go語言函數(shù)vmT.Set("getRandomInt",
func(call
otto.FunctionCall)
otto.Value
{
//
獲取調(diào)用該函數(shù)時傳入的參數(shù),maxA將作為生成隨機(jī)數(shù)的最大值上限
maxA,
_
:=
call.Argument(0).ToInteger()
randomNumberT
:=
rand.Intn(int(maxA))//
生成隨機(jī)整數(shù)
rs,
_
:=
otto.ToValue(randomNumberT)//
轉(zhuǎn)換為虛擬機(jī)中可以接受的類型
return
rs//
返回該值})
//
在虛擬機(jī)中運(yùn)行代碼vmT.Run(`
result1
=
a
+
2;
//
計算a+2的數(shù)值
console.log(text1
+
result1);
//
輸出信息
result2
=
getRandomInt(20);
//
調(diào)用Go語言中的函數(shù)獲取20以內(nèi)的隨機(jī)整數(shù)`)
//
從虛擬機(jī)中獲取變量的值if
valueT,
errT
:=
vmT.Get("result1");
errT
==
nil
{
if
valueIntT,
errT
:=
valueT.ToInteger();
errT
==
nil
{
fmt.Printf("result1:
%v\n",
valueIntT)
}}實現(xiàn)Lua語言虛擬機(jī)的/Shopify/go-lua包var
codeT
=
`--
輸出字符串print("開始運(yùn)行")
--
Lua中定義函數(shù)--
接受兩個參數(shù),并返回一個結(jié)果值function
AddTwice(a,
b)
return
a
+
b
+
bend
`
func
main()
{
vmT
:=
lua.NewState()
//
新建一個Lua虛擬機(jī)
lua.OpenLibraries(vmT)//
打開所有的Lua標(biāo)準(zhǔn)庫
//
執(zhí)行Lua腳本
if
errT
:=
lua.DoString(vmT,
codeT);
errT
!=
nil
{
panic(errT)
}
vmT.Global("AddTwice")//
獲取Lua中的函數(shù)
vmT.PushInteger(3)//
傳入?yún)?shù)
vmT.PushInteger(8)
vmT.Call(2,
1)//
調(diào)用該函數(shù),聲明有兩個參數(shù)和一個返回值
result2,
_
:=
vmT.ToInteger(1)//
獲取返回結(jié)果(參數(shù)中是結(jié)果序號)
fmt.Printf("返回結(jié)果為:%v",
result2)
vmT.Pop(1)//
從棧上彈出一個數(shù)值目錄導(dǎo)航18.3Go語言中直接執(zhí)行其他程序或調(diào)用系統(tǒng)命令Contents調(diào)用應(yīng)用程序或執(zhí)行系統(tǒng)命令//
分配用于存放調(diào)用程序輸出信息的緩沖區(qū)var
outBufT
bytes.Buffer
//
分配用于存放調(diào)用程序運(yùn)行發(fā)生錯誤時輸出錯誤信息的緩沖區(qū)var
errBufT
bytes.Buffer
//
創(chuàng)建執(zhí)行findstr命令的對象,第二個參數(shù)開始是命令行參數(shù)//
一個命令行參數(shù)作為exec.Command函數(shù)的一個參數(shù)cmdT
:=
exec.Command(`c:\Windows\System32\findstr.exe`,
`package`,
`c:\goprjs\src\tools\*.go`)
//
把調(diào)用程序的標(biāo)準(zhǔn)輸出指向outBufT//
標(biāo)準(zhǔn)輸出一般指的是程序正常執(zhí)行時輸出的信息cmdT.Stdout
=
&outBufT
//
把調(diào)用程序的標(biāo)準(zhǔn)錯誤輸出指向errBufT//
標(biāo)準(zhǔn)錯誤輸出一般指的是程序執(zhí)行出現(xiàn)異常時輸出的信息cmdT.Stderr
=
&errBufT
//
執(zhí)行該命令(或程序)errT
:=
cmdT.Run()使用操作系統(tǒng)的管道cmdT
:=
exec.Command(nameA,
argsA...)
pipeT,
errT
:=
cmdT.StdoutPipe()//
獲取該對象的標(biāo)準(zhǔn)輸出管道
readerT
:=
bufio.NewReader(pipeT)//
創(chuàng)建從管道中讀取內(nèi)容的bufio.Reader對象
go
func()
{//
啟動一個goroutine來讀取
for
{//
循環(huán)每次讀取一行,直至讀到io.EOF或出錯
inputT,
errT
:=
readerT.ReadString('\n')
if
errT
!=
nil
{
if
errT
==
io.EOF
{
return
}
tools.Printfln("從管道中讀取內(nèi)容時發(fā)生錯誤:%v",
errT)
return
}
tools.Printfln("%s",
inputT)
}}()
errT
=
cmdT.Start()目錄導(dǎo)航18.4Go語言與WebAssemblyContentsWebAssembly
簡稱Wasm,用其他語言編寫代碼,編譯成可以跨平臺執(zhí)行的特殊二進(jìn)制代碼在瀏覽器中執(zhí)行(JavaScript)WebAssemblyfmt.Printf("這是一個Go
WebAssembly的例子。\n")//
在瀏覽器的控制臺輸出信息
//
獲取網(wǎng)頁DOM對象中的輸入框var
input1
=
js.Global().Get("document").Call("getElementById",
"input1"
溫馨提示
- 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 借款合同利息條款的范例分析
- 環(huán)保節(jié)能洗車合同
- 共享服務(wù)合同范本在線問答
- 簽訂勞務(wù)分包合同的注意事項解析
- 預(yù)購合同的風(fēng)險評估
- 保證書范文撰寫心得
- 教輔資料購銷協(xié)議
- 預(yù)訂住房合同協(xié)議
- 三年級積極參與保證
- 保安服務(wù)提供合同
- 第六單元 寫作《表達(dá)要得體》公開課一等獎創(chuàng)新教案
- 犯罪學(xué)智慧樹知到期末考試答案章節(jié)答案2024年云南司法警官職業(yè)學(xué)院
- xxx軍分區(qū)安保服務(wù)項目技術(shù)方案文件
- 電感耦合等離子體發(fā)射光譜儀的維護(hù)和保養(yǎng)
- 2023年高二組重慶市高中學(xué)生化學(xué)競賽試題
- 2024-2030年中國新鮮果蔬行業(yè)市場發(fā)展分析及競爭策略與投資前景研究報告
- 物流配送合作協(xié)議書范本
- 機(jī)械制圖(山東聯(lián)盟)智慧樹知到期末考試答案章節(jié)答案2024年山東華宇工學(xué)院
- 在線網(wǎng)課《馬克思主義新聞思想(河北)》單元測試考核答案
- 2024年海南省海口四中高三3月份第一次模擬考試化學(xué)試卷含解析
- 人員招聘計劃方案
評論
0/150
提交評論