为了账号安全,请及时绑定邮箱和手机立即绑定

如何将戈朗字符串添加到 cgo 中的 c 结构中

如何将戈朗字符串添加到 cgo 中的 c 结构中

Go
30秒到达战场 2022-10-04 16:13:19
如何将 golang 字符串添加到我在 cgo 中制作的 c 结构中。代码如下:package main/*#include <stdio.h>#include <stdlib.h>#include <errno.h>typedef struct Point {    int x, y;} Point;typedef struct Resp {    char response;} Resp;*/import "C"import (    "fmt"    "io/ioutil"    "unsafe")type CPoint struct {    Point C.Point    Resp  C.Resp}func main() {    var r string = "Hello World"    resp := unsafe.Pointer(C.char(r))    point := CPoint{        Point: C.Point{x: 1, y: 2},        Resp: C.Resp{response: resp},    }    fmt.Println(point)}但是每当我运行这个,我得到这个错误如何解决这个问题?如何通过 r 键入 _Ctype_char?cannot convert r (type string) to type _Ctype_char另外,如何在 c 结构“Resp”中获取值?package main/*#include <stdio.h>#include <stdlib.h>#include <errno.h>typedef struct Point {    int x, y;} Point;typedef struct Resp {    char response; // <-- How can I get this value in my go code?} Resp;*/
查看完整描述

1 回答

?
森栏

TA贡献1810条经验 获得超5个赞

您的代码需要 2 个修复:

  1. C 仅表示单个字符/字节 - 不表示字符串。C 字符串为 。charchar*

  2. 您应该使用 从 Go 分配 C 字符串,并释放它。参见:https://pkg.go.dev/cmd/cgo#hdr-Go_references_to_CC.CStringC.free

以下是您使用这些修复程序的示例:

package main


// FIX: "char response" replaced with "char *response" below.


/*

#include <stdio.h>

#include <stdlib.h>

#include <errno.h>


typedef struct Point {

    int x, y;

} Point;


typedef struct Resp {

    char *response;

} Resp;


void fill(const char *name, Resp *r) {

   printf("name: %s\n", name);

   printf("Original value: %s\n", r->response);

   r->response = "testing";

}

*/

import "C"

import (

    "fmt"

    "unsafe"

)


// NOTE: You cannot pass this struct to C.

// Types passed to C must be defined in C (eg, like "Point" above).

type CPoint struct {

    Point C.Point

    Resp  C.Resp

}


func main() {

    // FIX: Use CString to allocate a *C.char string.

    resp := C.CString("Hello World")


    point := CPoint{

        Point: C.Point{x: 1, y: 2},

        Resp:  C.Resp{response: resp},

    }

    fmt.Println(point)


    // Example of calling a C function and converting a C *char string to a Go string:

    cname := C.CString("foo")

    defer C.free(unsafe.Pointer(cname))

    r := &C.Resp{

        response: resp, // Use allocated C string.

    }

    C.fill(cname, r)

    goResp := C.GoString(r.response)

    fmt.Println(goResp)


    // FIX: Release manually allocated string with free(3) when no longer needed.

    C.free(unsafe.Pointer(resp))

}


查看完整回答
反对 回复 2022-10-04
  • 1 回答
  • 0 关注
  • 64 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信