博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
go与c互相调用
阅读量:5866 次
发布时间:2019-06-19

本文共 1839 字,大约阅读时间需要 6 分钟。

此例子来自于go源码中,借此来和大家分享一下两者如何调用,网上很多文章语言不详,也没有一个完整的测试例子

  1. 目录结构

首先src 目录下有

testcgowin目录下:

这里的_obj目录是cgo生成的

这里需要展示的是go中如何调用c语言导出函数,以及在c语言中如何调用go的导出函数.

关键是cthread.go和cthread_windows.c两个文件

  1. go文件

cthread.go内容:

package ctestcgowin

// extern void doAdd(int, int);
import "C"
import (
"sync"
"fmt"
)
var sum struct {
sync.Mutex
i int
}
//export Add
func Add(x int) {
defer func() {
recover()
}()
sum.Lock()
sum.i += x
sum.Unlock()
var p *int
*p = 2
}
func TestCthread() {
sum.i = 0
C.doAdd(10, 6)
want := 10 * (10 - 1) / 2 * 6
if sum.i != want {
fmt.Printf("sum=%d, want %d\n", sum.i, want)
}
fmt.Println("want=",want)
}

这里的:

// extern void doAdd(int, int); import "C"

这两行非常关键,必须紧挨着,不能有空行,而且要紧跟着package语句,import要单独写

这里的注释相当于c语言声明了一个函数,你用#include当然也可以。遵循的都是c的语法,少个分号都是会报错的。

然后是下面两行:

//export Add func Add(x int) {

export Add表示这是go要导出的一个函数,这样c里面可以调用。

如果此行注释删掉,c文件将会提示找不到Add函数。

cthread_windows.c:18: undefined reference to `Add'

  1. c语言文件

// Copyright 2013 The Go Authors.  All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. #define WIN32_LEAN_AND_MEAN #include 
#include
#include "_cgo_export.h" __stdcall static unsigned int addThread(void *p) { int i, max; max = *(int*)p; for(i=0; i
MaxThread) nthread = MaxThread; for(i=0; i

 

我不晓得这个宏WIN32_LEAN_AND_MEAN什么意思,跟着写就行了,也没有去查阅文档以及代码。

这里doAdd是导出函数,addThread不需要导出,所以加了static,

#include "_cgo_export.h"是因为我们需要调用go的导出函数Add,有兴趣的可以看看_obj目录

到此为止,相互之间的关系已经说明白了,当然go与c语言之间的类型转换,留作以后再说。

  1. 编译生成.a文件

接下来如果想要利用这个lib,很简单,

运行cgo生成必要的文件,然后go install将编译生成testcgowin.a文件,此文件在pkg\windows_386目录下

  1. 利用.a文件

直接看testcgowin.go文件内容即可:

package main import "testcgowin" func main(){ ctestcgowin.TestCthread(); }

 

  1. 结语

c和go互相调用的关键都是通过注释实现的,并且cgo会自己编译相应的.c文件,不需要特别说明,只需要放到相应目录下即可。

总的来说go为了和c互操作做了很多,虽然没法像c++那么方便,但是基本上来收还是很顺利的。

转载地址:http://oennx.baihongyu.com/

你可能感兴趣的文章
高并发环境下,Redisson实现redis分布式锁
查看>>
java基础-System类常用方法介绍
查看>>
Java继承
查看>>
乌克兰基辅一世遗修道院起火 现场火光照亮夜空
查看>>
[iOS 10 day by day] Day 2:线程竞态检测工具 Thread Sanitizer
查看>>
将本地项目上传github
查看>>
Centos/Ubuntu下安装nodejs
查看>>
关于浏览器的cookie
查看>>
Hyper-V 2016 系列教程30 机房温度远程监控方案
查看>>
国内先进的智能移动广告聚合平台-KeyMob聚合
查看>>
我的友情链接
查看>>
ubuntu 镜像站部署
查看>>
Xshell 连接虚拟机慢 解决方案
查看>>
我的友情链接
查看>>
PHP - 如何打印函数调用树
查看>>
js闭包
查看>>
Swift笔记2
查看>>
进入docker的工作流程
查看>>
第二章 编程之道
查看>>
[原]用虚拟机搭建IOS开发环境的一些要点
查看>>