《Go语言从入门到精通》Go语言与其他语言的结合运用_第1页
《Go语言从入门到精通》Go语言与其他语言的结合运用_第2页
《Go语言从入门到精通》Go语言与其他语言的结合运用_第3页
《Go语言从入门到精通》Go语言与其他语言的结合运用_第4页
《Go语言从入门到精通》Go语言与其他语言的结合运用_第5页
已阅读5页,还剩16页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Go语言与其他语言的结合运用Go语言从入门到精通了解Cgo了解Go语言与WebAssembly的结合运用01CGO02SCRIPT03ASSEMBLYtarget目标了解几种Go语言中运行的脚本语言目录导航18.1CgoContentsCgo

直接调用C语言编写的函数库

Go语言最初最主要的优势之一可以直接利用庞大的C语言积累资源Cgo–先以类似注释的语法加入C语言代码package

main

/*#include

<stdio.h>#include

<stdlib.h>#include

<time.h>

//

是否初始化随机数种子的标志int

randomizeFlagG

=

0;

//

获取一个随机数int

getRandomInt(int

maxA)

{

if

(randomizeFlagG

==

0)

{

//

初始化随机数种子

srand(time(NULL));

}

//

限制随机数值范围

int

rs

=

rand()%maxA;

//

为了演示,在C语言函数中输出一下生成的随机数

printf("%d\n",

rs);

return

rs;}

//

输出一个字符串void

printString(char

*str)

{

printf("%s\n",

str);}

*/Cgo–然后再Go语言中调用import

"C"

import

(

"fmt"

"unsafe")

func

main()

{

//

调用C的标准库函数puts来输出

C.puts(C.CString("这是一个test."))

//

将Go语言字符串转换为C语言格式的字符串

cStrT

:=

C.CString("测试字符串")

//

调用C语言中自定义的函数来输出

C.printString(cStrT)

//

确保释放C语言格式的字符串所占用的内存空间

defer

C.free(unsafe.Pointer(cStrT))

//

调用C语言中定义的函数获取一个随机数

rs

:=

C.getRandomInt(20)

//

输出该随机数及其在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语言中编写函数供C语言调用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)}

//

必须要有一个主函数main,可以没有内容func

main()

{}gobuild-buildmode=c-shared-ocgo3.dllcgo3.go将生成cgo3.h和cgo3.dllC语言中调用Go函数的写法#include

"cgo3.h"

#include

<stdio.h>#include

<string.h>

int

main(){

char

strT[]

=

"随机数";

int

lenT

=

strlen(strT);

GoString

goStrT

=

{strT,

lenT};

printInGo(goStrT);

GoInt

randomT

=

getRandomInt(100);

printf("%s:

%lld\n",

strT,

randomT);

return

0;}Cgo的局限大多数数据类型在Go语言和C语言之间要做转换才能正确使用一些数据类型存在差异,稍不注意容易产生混淆,例如C语言中的int一般相当于Go语言中的int32,而longlong才相当于Go语言中的int64

cgo中不能支持C语言中printf这类函数中使用的可变个数的参数形式,无法直接在Go语言中调用C语言中的printf这一类的函数。目录导航18.2Go语言中运行其他脚本语言Contentstengo脚本语言(/d5/tengo)sum

:=

0

//

变量初始化和赋值语句与Go语言基本一致

a

:=

0

//

循环语句也很像Go语言中的//

变量maxA是将从Go语言中传递进来的for

a

<

maxA

{

sum

+=

a

a

++}

//

也有printf等内置函数//

times函数是在Go语言中定义的//

这里演示了在脚本语言中调用Go语言中代码的能力printf("%d\n",

times(2,

3,

4))创建tengo虚拟机并执行脚本//

新建一个脚本运行的虚拟机//

一般会编译为字节码准备运行s

:=

script.New([]byte(codeT))

//

向脚本执行环境(虚拟机VM)中传入变量maxA_

=

s.Add("maxA",

20)

//传入准备在虚拟机中执行的Go语言编写的函数times_

=

s.Add("times",

times)

//

执行脚本c,

err

:=

s.Run()if

err

!=

nil

{

panic(err)}

//

获取返回值(脚本中的sum变量)sumT

:=

c.Get("sum")

//

转换类型后输出fmt.Println(sumT.Int())实现JavaScript虚拟机的/robertkrimen/otto包vmT

:=

otto.New()//

新建Javascript虚拟机vmT.Set("a",

18)//

设置虚拟机中的变量a为数字18vmT.Set("text1",

"[计算结果]

")//

设置虚拟机中的变量text1为字符串

//

设置供虚拟中Javascript代码调用的Go语言函数vmT.Set("getRandomInt",

func(call

otto.FunctionCall)

otto.Value

{

//

获取调用该函数时传入的参数,maxA将作为生成随机数的最大值上限

maxA,

_

:=

call.Argument(0).ToInteger()

randomNumberT

:=

rand.Intn(int(maxA))//

生成随机整数

rs,

_

:=

otto.ToValue(randomNumberT)//

转换为虚拟机中可以接受的类型

return

rs//

返回该值})

//

在虚拟机中运行代码vmT.Run(`

result1

=

a

+

2;

//

计算a+2的数值

console.log(text1

+

result1);

//

输出信息

result2

=

getRandomInt(20);

//

调用Go语言中的函数获取20以内的随机整数`)

//

从虚拟机中获取变量的值if

valueT,

errT

:=

vmT.Get("result1");

errT

==

nil

{

if

valueIntT,

errT

:=

valueT.ToInteger();

errT

==

nil

{

fmt.Printf("result1:

%v\n",

valueIntT)

}}实现Lua语言虚拟机的/Shopify/go-lua包var

codeT

=

`--

输出字符串print("开始运行")

--

Lua中定义函数--

接受两个参数,并返回一个结果值function

AddTwice(a,

b)

return

a

+

b

+

bend

`

func

main()

{

vmT

:=

lua.NewState()

//

新建一个Lua虚拟机

lua.OpenLibraries(vmT)//

打开所有的Lua标准库

//

执行Lua脚本

if

errT

:=

lua.DoString(vmT,

codeT);

errT

!=

nil

{

panic(errT)

}

vmT.Global("AddTwice")//

获取Lua中的函数

vmT.PushInteger(3)//

传入参数

vmT.PushInteger(8)

vmT.Call(2,

1)//

调用该函数,声明有两个参数和一个返回值

result2,

_

:=

vmT.ToInteger(1)//

获取返回结果(参数中是结果序号)

fmt.Printf("返回结果为:%v",

result2)

vmT.Pop(1)//

从栈上弹出一个数值目录导航18.3Go语言中直接执行其他程序或调用系统命令Contents调用应用程序或执行系统命令//

分配用于存放调用程序输出信息的缓冲区var

outBufT

bytes.Buffer

//

分配用于存放调用程序运行发生错误时输出错误信息的缓冲区var

errBufT

bytes.Buffer

//

创建执行findstr命令的对象,第二个参数开始是命令行参数//

一个命令行参数作为exec.Command函数的一个参数cmdT

:=

exec.Command(`c:\Windows\System32\findstr.exe`,

`package`,

`c:\goprjs\src\tools\*.go`)

//

把调用程序的标准输出指向outBufT//

标准输出一般指的是程序正常执行时输出的信息cmdT.Stdout

=

&outBufT

//

把调用程序的标准错误输出指向errBufT//

标准错误输出一般指的是程序执行出现异常时输出的信息cmdT.Stderr

=

&errBufT

//

执行该命令(或程序)errT

:=

cmdT.Run()使用操作系统的管道cmdT

:=

exec.Command(nameA,

argsA...)

pipeT,

errT

:=

cmdT.StdoutPipe()//

获取该对象的标准输出管道

readerT

:=

bufio.NewReader(pipeT)//

创建从管道中读取内容的bufio.Reader对象

go

func()

{//

启动一个goroutine来读取

for

{//

循环每次读取一行,直至读到io.EOF或出错

inputT,

errT

:=

readerT.ReadString('\n')

if

errT

!=

nil

{

if

errT

==

io.EOF

{

return

}

tools.Printfln("从管道中读取内容时发生错误:%v",

errT)

return

}

tools.Printfln("%s",

inputT)

}}()

errT

=

cmdT.Start()目录导航18.4Go语言与WebAssemblyContentsWebAssembly

简称Wasm,用其他语言编写代码,编译成可以跨平台执行的特殊二进制代码在浏览器中执行(JavaScript)WebAssemblyfmt.Printf("这是一个Go

WebAssembly的例子。\n")//

在浏览器的控制台输出信息

//

获取网页DOM对象中的输入框var

input1

=

js.Global().Get("document").Call("getElementById",

"input1"

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论