温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

golang与c语言是怎么相互调用

发布时间:2021-11-25 15:03:30 来源:亿速云 阅读:120 作者:小新 栏目:编程语言

这篇文章主要为大家展示了“golang与c语言是怎么相互调用”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“golang与c语言是怎么相互调用”这篇文章吧。

go语言调用c语言

以下为一个简短的例子:

package main

// #include <stdio.h>
// #include <stdlib.h>
/*
void print(char *str) {
    printf("%s\n", str);
}
*/
import "C"

import "unsafe"

func main() {
    s := "Hello Cgo"
    cs := C.CString(s)
    C.print(cs)
    C.free(unsafe.pointer(cs))
}

与“正常”的go代码相比,上述代码有几处“特殊”的地方:

  • 在开头的注释中出现了c语言头文件的include字样

  • 在注释中定义了c语言函数print

  • import了一个名为C的“包”

  • 在main函数中调用了上述定义的c语言函数print

首先,go源码文件中的c语言代码是需要用注释包裹的,就像上面的include头文件以及print函数定义;其次,import "C"这个语句是必须的,而且其与上面的c代码之间不能用空行分隔,必须紧密相连。这里的”C“不是包名,而是一种类似名字空间的概念,或可以理解为伪包,c语言所有语法元素均在该伪包下面;最后,访问c语法元素时都要在其前面加上伪包前缀,比如C.uint和上面代码中的C.print、C.free等。

更详细的在go中调用c语言的用法可以参考Go与C语言的互操作,本文不再一一细述。

在上面的例子中,c语言是内嵌在go代码中的,如果代码量更大更复杂的话,这显然是很不”专业“的。那么,是否可以将c语言代码从go代码中分离出去,单独定义呢?答案是肯定的,可以通过共享库的方式实现。

cgo提供了#cgo指示符可以指定go源码在编译后与哪些共享库进行链接。例子如下:

// hello.go
package main

// #cgo LDFLAGS: -L ./ -lhello
// #include <stdio.h>
// #include <stdlib.h>
// #include "hello.h"
import "C"

func main() {
    C.hello()
}

// hello.c
#include "hello.h"

void hello()
{
    printf("hello, go\n");
}

// hello.h
extern void hello();

其中在hello.go中,#cgo指示符后面添加LDFLAGS: -L ./ -lhello,作用是在go代码编译时,指定在当前目录查找so库并进行链接。

因此,只需要把hello.c编译成动态库,再编译go代码,即可在运行go代码的时候调用共享库中的c语言函数。指令如下:

  • gcc -fPIC -o libhello.so hello.c

  • go build -o hello

  • ./hello

c语言调用go语言

与在go中调用c源码相比,在c中使用go函数的场合较少。因为一般来说,采用高级语言作为粘合剂调用低级语言能充分发挥各自的特点,而用低级语言调用高级语言反而有可能降低低级语言的性能优势,在go中,可以使用”export + 函数名“来导出go函数为c代码所用,看一个简单的例子:

// hello.go
package main

import "C"

import "fmt"

// export Go2C
func Go2C() {
    fmt.Println("hello, C")
}

可通过go build的编译选项,将go代码编译成共享库以供c代码调用。注意,编译so库时必须存在main及main函数(即使main函数为空)。编译指令如下:go build -v -x -buildmode=c-shared -o libhello.so hello.go

编译成功后,只需在c代码中引入新生成的头文件及编译时链接动态库即可实现go函数的调用。代码如下:

// hello.c
#include <stdio.h>
#include "libhello.h"

int main()
{
    Go2C();
    return 0;
}

通过gcc -o hello -L. -lhello,即可编译成可执行程序。注意,运行前必须确定共享库运行时查找路径中存在需要链接的共享库,可通过将so库路径放到/usr/lib或者修改环境变量LD_LIBRARY_PATH。

以上是“golang与c语言是怎么相互调用”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI