叮当猫咪
您遇到的一个问题是,在对 C 代码的调用中,您可能无法将指针传递给 Go 指针。该变量是一个 ,但是一个 Go 指针,因此您不能使用它(或者更确切地说,您不能在 a_add 字段中将其用作值)。filedescriptorC.int&filedescriptor关于你的C代码有很多我不清楚的地方,但你可以使用下面的代码。请注意,对于您的特定情况,此代码可能有些过头了。它并不意味着特别高效或良好,在非常灵活的同时尽可能清晰 - 例如,它可以读取和写入打包的C结构。package main// #include <stdio.h>// #include <stdlib.h>// #include <string.h>//// struct data {// char *a_add;// unsigned int length;// };//// void f(struct data *p) {// printf("p->a_add = %p, p->length = %u\n", p->a_add, p->length);// printf("p->a_add as an int: %d\n", *(int *)p->a_add);// *(int *)p->a_add = 0x12345678;// }import "C"import ( "fmt" "unsafe")const cIntSize = C.sizeof_int// Produce a Go int64 from a C int. The caller passes the address// of the C int.func int64FromCInt(ci unsafe.Pointer) int64 { // Get a slice pointing to the bytes of the C int. sci := (*[cIntSize]byte)(ci)[:] switch { case cIntSize == unsafe.Sizeof(int64(0)): var gi int64 sgi := (*[unsafe.Sizeof(gi)]byte)(unsafe.Pointer(&gi))[:] copy(sgi, sci) return gi case cIntSize == unsafe.Sizeof(int32(0)): var gi int32 sgi := (*[unsafe.Sizeof(gi)]byte)(unsafe.Pointer(&gi))[:] copy(sgi, sci) return int64(gi) case cIntSize == unsafe.Sizeof(int(0)): var gi int sgi := (*[unsafe.Sizeof(gi)]byte)(unsafe.Pointer(&gi))[:] copy(sgi, sci) return int64(gi) default: panic("no Go integer size matches C integer size") }}// Write C int (via an unsafe.Pointer) from Go int. The caller// passes the address of the C int.func writeCIntFromInt(gi int, ci unsafe.Pointer) { // Get a slices covering the bytes of the C int. sci := (*[cIntSize]byte)(ci)[:] switch { case cIntSize == unsafe.Sizeof(gi): sgi := (*[unsafe.Sizeof(gi)]byte)(unsafe.Pointer(&gi))[:] copy(sci, sgi) case cIntSize == unsafe.Sizeof(int64(0)): // Copy value to int64 for copying purposes. // Since int64 holds all int values, this always works. gi2 := int64(gi) sgi := (*[unsafe.Sizeof(gi)]byte)(unsafe.Pointer(&gi2))[:] copy(sci, sgi) case cIntSize == unsafe.Sizeof(int32(0)): // Copy value to int32 for copying purposes. // Panic if we destroy the value via truncation. gi2 := int32(gi) if int(gi2) != gi { panic(fmt.Sprintf("unable to send Go value %x to C: size of Go int=%d, size of C int=%d", gi, unsafe.Sizeof(gi), cIntSize)) } sgi := (*[unsafe.Sizeof(gi)]byte)(unsafe.Pointer(&gi2))[:] copy(sci, sgi) default: panic("no Go integer size matches C integer size") }}func main() { b := C.malloc(cIntSize) defer C.free(b) writeCIntFromInt(32767, b) d := C.struct_data{a_add: (*C.char)(b), length: cIntSize} fmt.Println("calling C.f(d)") C.f(&d) result := int64FromCInt(unsafe.Pointer(d.a_add)) fmt.Printf("result = %#x\n", result)}