本文共 1839 字,大约阅读时间需要 6 分钟。
此例子来自于go源码中,借此来和大家分享一下两者如何调用,网上很多文章语言不详,也没有一个完整的测试例子
首先src 目录下有
testcgowin目录下:
这里的_obj目录是cgo生成的
这里需要展示的是go中如何调用c语言导出函数,以及在c语言中如何调用go的导出函数.
关键是cthread.go和cthread_windows.c两个文件
cthread.go内容:
package ctestcgowin// extern void doAdd(int, int);import "C"import ("sync" "fmt")var sum struct { sync.Mutex i int}//export Addfunc Add(x int) { defer func() { recover() }() sum.Lock() sum.i += x sum.Unlock()var p *int *p = 2}func TestCthread() { sum.i = 0C.doAdd(10, 6) want := 10 * (10 - 1) / 2 * 6if 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'
// 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语言之间的类型转换,留作以后再说。
接下来如果想要利用这个lib,很简单,
运行cgo生成必要的文件,然后go install将编译生成testcgowin.a文件,此文件在pkg\windows_386目录下
直接看testcgowin.go文件内容即可:
package main import "testcgowin" func main(){ ctestcgowin.TestCthread(); }
c和go互相调用的关键都是通过注释实现的,并且cgo会自己编译相应的.c文件,不需要特别说明,只需要放到相应目录下即可。
总的来说go为了和c互操作做了很多,虽然没法像c++那么方便,但是基本上来收还是很顺利的。
转载地址:http://oennx.baihongyu.com/