go往c里面设置回调函数,并且回调函数的参数为结构体

看了下go往c里面设置回调函数的例子,里面的回调函数的参数都是简单的类型,char *和int,今天在此举一个结构体为回调参数的例子。
头文件为GoDll.h,内容如下:
#ifndef __GO_DLL_H__
#define __GO_DLL_H__
/*C代码头文件需要添加类似如下声明*/

typedef struct CMyCallBack_
{
	int iLen;
	char szVal[100];
}CMyCallBack;

typedef int (*fnc)(CMyCallBack* myCallBack); // 回调函数的名称为 fnc,参数是CMyCallBack *
void printHello();
void callBack(fnc f);

#endif

实现文件为GoDll.c,内容如下:

#include "GoDll.h"
#include <stdio.h>
#include <string.h>

void printHello()
{
	printf("printHello\n");
}

void callBack(fnc f)
{
	CMyCallBack myCallBack;
	strcpy(myCallBack.szVal, "hello world");
	myCallBack.iLen = strlen(myCallBack.szVal);
	f(&myCallBack);
}

经过 gcc -fPIC -shared GoDll.c -o libGoDll.so

然后将libGoDll.so和GoDll.h拷贝到go目录下,写两个go文件,cfuns.go和main.go
其中cfuns.go的内容如下:

package main

/*
#include <stdio.h>
#include "GoDll.h"
// The gateway function
int printMyCallBack_cgo(CMyCallBack *myCallBack)
{
	int printMyCallBack(int, char *);
	printf("val is %s\n", myCallBack->szVal);
	return printMyCallBack(myCallBack->iLen, (char *)myCallBack->szVal);
}
*/
import "C"

type MY_CALLBACK struct {
	iLen int
	strVal string
}

main.go的内容如下:

package main

/*
#cgo CFLAGS: -I./
#cgo LDFLAGS: -L./ -lGoDll
#include "GoDll.h"
int printMyCallBack_cgo(CMyCallBack *myCallBack);
*/
import "C"
import (
	"fmt"
	"unsafe"
)

//export printMyCallBack
func printMyCallBack(iLen C.int, strVal *C.char) int {
	fmt.Printf("len is %d\n", iLen);
	fmt.Printf("value is %s\n", C.GoString(strVal));
	return 0;
}

func main(){
	fmt.Println("in main")
	C.printHello()
	C.callBack((C.fnc)(unsafe.Pointer(C.printMyCallBack_cgo)))
}

需要注意的地方:
1.func printMyCallBack上面的//export printMyCallBack不可少
2.int printMyCallBack_cgo(CMyCallBack *myCallBack);声明不可少
3.go语言的指针不能直接设置成C语言里面的回调函数指针,需要进行中转,比如上面的 printMyCallBack_cgo就是中转函数。
4.c语言里面能调用go函数,不过此go函数需要导出,比如上面的printMyCallBack就需要导出。
5.go函数并没有导出成下面这种样式
func printMyCallBack(myCallBack *C.CMyCallBack) int {

}
主要是因为CMyCallBack里面的char szVal[100];不好转换,用各种办法,一直转换出错。所以干脆拆开。

猜你喜欢

转载自blog.csdn.net/tusong86/article/details/107697905