Golang Go语言中CGO的参数要怎么传?

发布于 1周前 作者 itying888 来自 Go语言

Golang Go语言中CGO的参数要怎么传?

package main

/* #include <stdio.h> unsigned short crc_ccitt(unsigned char *q, int len) { int i, j; int c, crc = 0xffff; for(i=0; i<len; i++) { c = q[i] & 0x00ff; crc ^= c; for(j=0; j<8; j++) { if((crc&0x0001) != 0) { crc >>= 1; crc ^= 0xA001; } else { crc >>= 1; } } } return (unsigned short)crc; } */ import “C” import ( “fmt” “unsafe” )

func Crc() { data := []byte{0x99, 0x88, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x0e, 0x0c, 0x32, 0x31, 0x30, 0x31, 0x31, 0x38, 0x30, 0x37, 0x30, 0x30, 0x31, 0x30, 0x18} crc := C.crc_ccitt((*C.uchar)(unsafe.Pointer(&data)), C.int(len(data))) // 期望结果 56 f9 fmt.Printf("%X", crc) }

func main() { Crc() }

有个 CRC 校验的东西是 C 写的,我就想着难得去用 go 实现直接 CGO 调用,发现这个参数怎么传都不对,请教下各位大神,谢谢


更多关于Golang Go语言中CGO的参数要怎么传?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html

8 回复

试了一下,
data := [26]byte{
0x99, 0x88, 0x02, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x0a,
0x00, 0x0e, 0x0c, 0x32, 0x31,
0x30, 0x31, 0x31, 0x38, 0x30,
0x37, 0x30, 0x30, 0x31, 0x30,
0x18}
这样能返回 F9 56

更多关于Golang Go语言中CGO的参数要怎么传?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


偏一下题,有这个调试的时间还不如直接 go 实现了,或者关键词 golang ccitt 就有相应的代码实现。另外提醒一下,cgo 其实调用是比较慢的,如果调用频繁的话,非常影响性能。

地址不对
crc := C.crc_ccitt((*C.uchar)(unsafe.Pointer(&data[0])), C.int(len(data)))

反复试过了 楼上的是正确答案

恩 后期还是用 golang 去实现比较好,CGO 的交叉编译也是个坑

在Go语言中,CGO允许你调用C语言的代码,实现Go与C语言的互操作。当你需要从Go代码中向C代码传递参数时,需要注意数据类型的匹配和内存管理。

首先,你需要确保Go和C之间的数据类型能够正确映射。例如,Go的intfloat64等基本类型可以直接映射到C的intdouble等类型。对于复杂类型如结构体,你需要使用C.struct_name的形式在Go中定义对应的C结构体,并确保字段类型匹配。

传递参数时,可以直接在CGO调用的C函数中使用Go变量。例如:

/*
#include <stdio.h>

void printInt(int i) {
    printf("%d\n", i);
}
*/
import "C"
import "unsafe"

func main() {
    i := 42
    C.printInt(C.int(i))
}

在这个例子中,我们将Go的int变量i转换为C的int类型,然后传递给C函数printInt

需要注意的是,对于指针和字符串等复杂类型,你需要使用unsafe.Pointer进行类型转换,并确保在Go侧管理好内存,以避免内存泄漏或野指针问题。对于字符串,通常会先将其转换为C风格的字符串(即以null结尾的字符数组),然后再传递给C函数。

总之,在Go中使用CGO传递参数时,关键在于确保类型匹配和正确管理内存。

回到顶部