cgo快速入门之golang调用C语言

前言

cgo 提供了 golang 和 C 语言相互调用的机制。几乎所有的编程语言都有C语言的影子,当然golang也不例外。可以看到golang的创始者们与C语言有着密切的联系。下面我们将通过快速入门小例子来掌握cgo的基本用法。

最简cgo程序

真实的cgo程序一般都比较复杂。不过我们可以通过一个小例子,了解一个最简的cgo程序该是什么样的。

构造一个最简cgo程序,首先要忽视一些复杂的cgo特性,同时要展示cgo程序和纯Go程序的差别来。

在使用cgo特性之前,需要安装C/C++构建工具链,在macOS和Linux下是要安装gcc,在windows下是需要安装MinGW工具。

下面是我们构建的最简cgo程序:

package main

import "C"

func main() {
    println("hello cgo")
}

编译输出:

在这里插入图片描述
对上面的代码进行说明。代码通过import "C"语句启用cgo特性,主函数只是通过Go内置的println函数输出字符串,其中并没有任何和cgo相关的代码。虽然没有调用cgo的相关函数,但是go build命令会在编译和链接阶段启动gcc编译器,这已经是一个完整的cgo程序了。

基于C标准库函数

//main.go
package main
/*
#include <stdlib.h>
*/
import "C"
import (
	"fmt"
	"time"
)
func main() {
	C.srandom(C.uint(time.Now().UTC().UnixNano()))
	for i := 0; i < 10; i++ {
		fmt.Printf("%d ", int(C.random()))
	}
	fmt.Println()
}

编译输出:
在这里插入图片描述
我们不仅仅通过import "C"语句启用cgo特性,同时包含C语言的#include <stdlib.h>头文件。

注意下:

可以用注释符//和/**/包围C代码
import “C” 和包含C代码之间是没有空行的

如果你运行go tool cgo main.go转换上面的例子,你会发现在本地文件夹下生成了一个_obj的文件夹:

在这里插入图片描述它会包含一个编译器在编译这些C文件后生成的目标文件cgo.o。

使用自己的C函数

前面我们使用了标准库中已有的函数。现在我们先自定义一个叫SayHello的C函数来实现打印,然后从Go语言环境中调用这个SayHello函数:

// main.go
package main

/*
#include <stdio.h>

static void SayHello(const char* s) {
    puts(s);
}
*/
import "C"

func main() {
    C.SayHello(C.CString("Hello, World"))
}

编译输出:

在这里插入图片描述
除了SayHello函数是我们自己实现的之外,其它的部分和前面的例子基本相似。

我们也可以将SayHello函数放到当前目录下的一个C语言源文件中(后缀名必须是.c)。因为是编写在独立的C文件中,为了允许外部引用,所以需要去掉函数的static修饰符。

#include <stdio.h>

void SayHello(const char* s) {
    puts(s);
}

然后在CGO部分先声明SayHello函数,其它部分不变:

package main

//void SayHello(const char* s);
import "C"

func main() {
    C.SayHello(C.CString("Hello, World"))
}

编译:
在这里插入图片描述
注意,如果之前运行的命令是go run hello.go或go build hello.go的话,此处须使用go run .或go build .

在这里插入图片描述
既然SayHello函数已经放到独立的C文件中了,我们自然可以将对应的C文件编译打包为静态库或动态库文件供使用,关于静态库和动态库以后再讲解。

总结

Go导出函数供C开发者使用(目前这种需求应该很少见),如果你正准备使用Go开发你的程序,或者你正将一个C构建的项目转换成Go项目,请尽量使用Go构建你的项目,而不是偷巧的导入C代码,尽量保持Go项目的纯粹。

参考:
https://chai2010.cn/advanced-go-programming-book/ch2-cgo/ch2-01-hello-cgo.html

在这里插入图片描述
欢迎关注公众号【程序猿编码】,添加本人微信号(17865354792),回复:领取学习资料,网盘资料有如下:

在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Windows 系统下,使用 Golang 调用 C 语言开源库 libxslt 可以通过以下步骤完成: 1. 安装 libxslt 在 Windows 上,可以通过 Cygwin 或 MinGW 等工具链来安装 libxslt 库。 2. 编写 C 语言代码 编写 C 语言代码,实现 libxslt 库的功能,并将其编译为动态链接库(.dll)文件。 例如,以下是一个使用 libxslt 库将 XML 文件转换为 HTML 文件的 C 语言代码: ```c #include <stdio.h> #include <string.h> #include <libxslt/xslt.h> #include <libxslt/transform.h> int transform(char *xml, char *xsl, char *output) { xmlDocPtr doc, res; xsltStylesheetPtr sty; const char *params[1] = { NULL }; int ret; xmlInitParser(); LIBXML_TEST_VERSION doc = xmlReadMemory(xml, strlen(xml), "noname.xml", NULL, 0); sty = xsltParseStylesheetFile((const xmlChar *)xsl); res = xsltApplyStylesheet(sty, doc, params); xmlSaveFormatFile(output, res, 1); xsltFreeStylesheet(sty); xmlFreeDoc(doc); xmlFreeDoc(res); xmlCleanupParser(); return ret; } ``` 将上述代码编译为动态链接库,可使用以下命令: ``` gcc -shared -o libxslt.dll -I/path/to/libxslt/include -L/path/to/libxslt/lib -lxslt -lz -lm xslt.c ``` 其中,`/path/to/libxslt` 为 libxslt 库的安装目录。 3. 使用 CGO 调用 C 函数 在 Golang 中,使用 CGO 可以调用 C 函数。在调用 C 函数前,需要将 C 函数声明为外部函数。 例如,以下是一个使用 CGO 调用上述 C 函数的 Golang 代码: ```go package main // #cgo LDFLAGS: -L./ -lxslt // int transform(char *xml, char *xsl, char *output); import "C" import "fmt" func main() { xml := "<xml>...</xml>" xsl := "<xsl>...</xsl>" output := "output.html" ret := C.transform(C.CString(xml), C.CString(xsl), C.CString(output)) fmt.Println(ret) } ``` 在编译 Golang 代码时,需要指定 libxslt 库的链接标志 `-L` 和 `lxslt`。 以上就是在 Windows 系统下,使用 Golang 调用 C 语言开源库 libxslt 的步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值