Go 通过Cgo传递函数指针给 C函数。 来设置回调函数。将void*转为[]byte获取数据。

经常可以遇到这样的SDK,需要传递一个回调函数。例如:
通过回调的方式将数据返回给调用者。 在回调结束之后 void* a 里存的数据就会被释放。
test.h

#ifndef __TEST_H__
#define __TEST_H__
#ifdef __cplusplus
extern "C"{
   
#endif

#define API __attribute__((visibility("default")))

typedef struct info{
   
    void* a;
    int  size;
}tInfo;

typedef int(*cb) (tInfo* n);


API int setcallback(cb s);

API void call()
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
要将含有多个字符串和整型数据的复杂结构体从Go传递给C函数,首先需要在Go中定义一个与C结构体相对应的Go结构体,并使用C语言的数据类型(如C.CString)将字符串转换为C字符串。例如: ```go package main /* #include <stdio.h> #include <stdlib.h> typedef struct { int id; char *name; char *address; } Person; void print_person(Person *p) { printf("ID: %d\n", p->id); printf("Name: %s\n", p->name); printf("Address: %s\n", p->address); } */ import "C" import ( "unsafe" ) type Person struct { ID int Name string Address string } func main() { p := Person{ ID: 1, Name: "John Doe", Address: "123 Main St", } cName := C.CString(p.Name) cAddress := C.CString(p.Address) defer C.free(unsafe.Pointer(cName)) defer C.free(unsafe.Pointer(cAddress)) cPerson := C.Person{ id: C.int(p.ID), name: cName, address: cAddress, } C.print_person(&cPerson) } ``` 在这个例子中,我们首先在Go中定义了一个Person结构体,然后在C中定义了一个相应的Person结构体。我们使用C语言的数据类型将Go中的字符串转换为C字符串,并将Go中的整型数据转换为C中的整型数据。最后,我们将转换后的C结构体传递给C函数print_person。 要让C回调函数返回复杂的结构体给Go,可以使用Go中的CGO特性。首先,在Go中定义一个函数类型作为回调函数的签名。例如: ```go type Callback func(int, string) Person ``` 然后,在C函数中调用该回调函数并将结果返回给Go。例如: ```c #include <stdio.h> #include <stdlib.h> typedef struct { int id; char *name; char *address; } Person; typedef Person (*Callback)(int, char *); Person *get_person(Callback callback) { Person *p = malloc(sizeof(Person)); p->id = 1; p->name = "John Doe"; p->address = "123 Main St"; (*callback)(p->id, p->name, p->address); return p; } ``` 在这个例子中,我们首先在C中定义了一个函数指针类型Callback作为回调函数的签名,并在get_person函数中使用该回调函数。在回调函数中,我们将结果封装到Person结构体中,并将其返回给Go。 最后,在Go中调用C函数传递回调函数作为参数。例如: ```go package main /* #include <stdio.h> #include <stdlib.h> typedef struct { int id; char *name; char *address; } Person; typedef Person (*Callback)(int, char *); Person *get_person(Callback callback) { Person *p = malloc(sizeof(Person)); p->id = 1; p->name = "John Doe"; p->address = "123 Main St"; (*callback)(p->id, p->name, p->address); return p; } */ import "C" import ( "fmt" "unsafe" ) type Person struct { ID int Name string Address string } type Callback func(int, string, string) func main() { callback := Callback(func(id int, name string, address string) { p := Person{ ID: id, Name: name, Address: address, } fmt.Printf("%+v\n", p) }) cCallback := C.Callback(unsafe.Pointer(&callback)) C.get_person(cCallback) } ``` 在这个例子中,我们首先在Go中定义了一个函数类型Callback作为回调函数的签名。然后,在main函数中,我们将该回调函数封装为Callback类型,并使用C语言的数据类型将其转换为C指针类型。最后,我们将该指针传递给C函数get_person,并在回调函数中将结果封装到Person结构体中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值