Golang中无法将CallBack(类型func(*_Ctype_char, *_Ctype_char, _Ctype_ulong))作为*[0]byte类型参数传递给_Cfunc_reload_pattern_db

Golang中无法将CallBack(类型func(*_Ctype_char, _Ctype_char, _Ctype_ulong))作为[0]byte类型参数传递给_Cfunc_reload_pattern_db 我遇到了以下问题:

我有一个需要从C代码调用的GO代码:

var field_mappings map[string]string = map[string]string{
" A": "a",
"B": "b",
"C": "c",
"D": "d"}

//export CallBack
func CallBack(key *C.char, value *C.char, value_len C.size_t){

if remap, ok := field_mappings[key]; ok {
    fmt.Println(key, remap)
}

}

我将这个回调方法传递给C函数

func ReloadPatternDB(opts Y){

x := C.CString(opts.x)
C.reload_pattern_db(x, CallBack);

}
int reload_pattern_db(const gchar* filename, key_value_cb cb)
{

//
}

以下是我的C头文件:

#ifndef _TEST_H_
#define _TEST_H_

#include <stdlib.h>

typedef void (*key_value_cb)(const char* key, const char* value, size_t value_len);
int initialize_engine(const char* filename, const char* module_path, key_value_cb cb);
int reload_pattern_db(const char* filename, key_value_cb cb);
void match(const char* pattern, size_t pattern_len, const char* program, size_t program_len);

#endif

当我编译GO代码时,出现以下错误:

command-line-arguments
./main.go:80:32: cannot use key (type *_Ctype_char) as type string in map index
./main.go:91:21: cannot use CallBack (type func(*_Ctype_char, *_Ctype_char, _Ctype_ulong)) as type *[0]byte in argument to _Cfunc_reload_pattern_db
./main.go:143:21: cannot use CallBack (type func(*_Ctype_char, *_Ctype_char, _Ctype_ulong)) as type *[0]byte in argument to

我是GO和CGO的新手。有人能指出错误并帮助我吗?

谢谢


更多关于Golang中无法将CallBack(类型func(*_Ctype_char, *_Ctype_char, _Ctype_ulong))作为*[0]byte类型参数传递给_Cfunc_reload_pattern_db的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang中无法将CallBack(类型func(*_Ctype_char, *_Ctype_char, _Ctype_ulong))作为*[0]byte类型参数传递给_Cfunc_reload_pattern_db的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


问题在于Go和C之间的类型转换不匹配。以下是解决方案:

问题1:回调函数类型不匹配

C函数需要的是函数指针类型,但Go传递的是函数值。需要使用C.key_value_cb类型进行转换:

//export CallBack
func CallBack(key *C.char, value *C.char, value_len C.size_t) {
    // 回调实现
}

func ReloadPatternDB(opts Y) {
    x := C.CString(opts.x)
    defer C.free(unsafe.Pointer(x))
    
    // 将Go回调函数转换为C函数指针类型
    cb := C.key_value_cb(C.CallBack)
    C.reload_pattern_db(x, cb)
}

问题2:C字符串到Go字符串的转换

不能在map中直接使用*C.char,需要先转换为Go字符串:

//export CallBack
func CallBack(key *C.char, value *C.char, value_len C.size_t) {
    // 将C字符串转换为Go字符串
    goKey := C.GoString(key)
    
    if remap, ok := field_mappings[goKey]; ok {
        fmt.Println(goKey, remap)
    }
}

完整修正代码:

package main

/*
#include "test.h"
#include <stdlib.h>
*/
import "C"
import (
    "fmt"
    "unsafe"
)

var field_mappings map[string]string = map[string]string{
    "A": "a",
    "B": "b",
    "C": "c",
    "D": "d",
}

//export CallBack
func CallBack(key *C.char, value *C.char, value_len C.size_t) {
    goKey := C.GoString(key)
    goValue := C.GoStringN(value, C.int(value_len))
    
    if remap, ok := field_mappings[goKey]; ok {
        fmt.Printf("Key: %s, Remapped: %s, Original Value: %s\n", goKey, remap, goValue)
    }
}

func ReloadPatternDB(opts Y) {
    x := C.CString(opts.x)
    defer C.free(unsafe.Pointer(x))
    
    cb := C.key_value_cb(C.CallBack)
    C.reload_pattern_db(x, cb)
}

关键修改点:

  1. 使用C.key_value_cb(C.CallBack)将Go回调函数转换为C函数指针类型
  2. 使用C.GoString()C.GoStringN()将C字符串转换为Go字符串
  3. 添加defer C.free()来释放C字符串内存
  4. 导入unsafe包用于指针操作

这些修改应该能解决编译错误并使回调函数正常工作。

回到顶部