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

本文详细介绍了如何在Go和C语言之间通过结构体进行回调函数的交互。通过一个具体示例,展示了如何定义和使用带有结构体参数的回调函数,包括头文件声明、实现文件编写、GCC编译及Go调用C函数的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

看了下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];不好转换,用各种办法,一直转换出错。所以干脆拆开。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值