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

将结构数组从C++传递到 GO

将结构数组从C++传递到 GO

函数式编程 2022-09-12 16:33:11
我试图从C++到golang获得一系列张量流盒预测,但无论我做什么,我都无法做到这一点。我有一个GO程序,它调用一个函数,该函数使用cgo在C++中执行张量流检测。这一切都有效,我能够在C++中得到预测。问题是将这些预测转换为GO作为100个结构的数组,每个结构包含一个预测。我可以在GO中设置一个指针,并使用此指针地址在C++中设置一个结构。下面显示了此代码。我想在 C++ 中设置一个结构数组,并在 GO 中检索此数组。我认为使用与之前相同的指针地址并将其用作我的C++数组的地址应该很容易。然后,我可以从 GO 中的指针还原结构。有没有人对此有解决方案?去type PredictResult struct {    Loc   [4]float32    Score int    Label int}var predictions PredictResultpredictions_ptr := unsafe.Pointer(&predictions)C.LIB_predict(predictions_ptr)fmt.Println("GO predictions; ", predictions)桥struct PredictResult{    float Loc[4];    int64_t Score;    int64_t Label;};void LIB_predict(void* predictions);桥.cppvoid LIB_predict(void* predictions){PredictResult *p = (PredictResult*)predictions;    p->Score = 6;    p->Label = 95;}指纹:GO predictions;  {[0 0 0 0] 6 95}
查看完整描述

2 回答

?
慕容708150

TA贡献1831条经验 获得超4个赞

假设您的C函数返回数组为,并且假设您知道返回的数组的长度(在下面的示例中,我假设为10,但您可以用任何有效的方法替换它),这种方法应该有效:PredictResult*


// #include <stdio.h>

// #include <stdlib.h>

//

// typedef struct PredictResult {

//     float Loc[4];

//     int64_t Score;

//     int64_t Label;

// } PredictResult;

//

// PredictResult* getOneResult() {

//   PredictResult* p = (PredictResult*)calloc(1, sizeof(PredictResult));

//   p->Score = 10;

//   p->Label = 99;

//   p->Loc[1] = 2.5;

//   p->Loc[3] = 3.5;

//   return p;

// }

//

// PredictResult* getTenResults() {

//   PredictResult* parr = (PredictResult*)calloc(10, sizeof(PredictResult));

//   parr[0].Score = 10;

//   parr[0].Label = 99;

//   parr[0].Loc[1] = 2.5;

//   parr[0].Loc[3] = 3.5;

//

//   parr[4].Score = 44;

//   parr[4].Label = 123;

//   parr[4].Loc[1] = 12.25;

//   parr[4].Loc[3] = -40.5;

//   return parr;

// }

//

//

import "C"


type PredictResult C.struct_PredictResult


func main() {

    p := C.getOneResult()

    if p == nil {

        log.Fatal("got nil")

    }


    pp := (*PredictResult)(p)

    fmt.Println(pp)


    parr := C.getTenResults()

    if parr == nil {

        log.Fatal("got nil")

    }


    pslice := (*[1 << 28]PredictResult)(unsafe.Pointer(parr))[:10:10]

    fmt.Println(pslice)

}

您最感兴趣的是如何将 的结果转换为相应结构类型的 Go 切片。这是采用Go维基上推荐的技术。getTenResults


根据C函数的确切签名,您可能需要在部件中编写一个“桥接”函数,以提供方便Go的数据,但这是它的基本要点。import "C"


或者,如果您希望在 Go 端分配切片并传入指向 C 的指针以进行填充,则可以执行以下操作:


// void PopulateTenResults(void* arr) {

//   PredictResult* parr = (PredictResult*)arr;

//   parr[1].Score = 210;

//   parr[1].Label = 299;

//   parr[1].Loc[1] = 22.5;

//   parr[1].Loc[3] = 23.5;

//

//   parr[8].Score = 344;

//   parr[8].Label = 3123;

//   parr[8].Loc[1] = 312.25;

//   parr[8].Loc[3] = -340.5;

// }

//

//

import "C"

然后在围棋中做:


prslice := make([]PredictResult, 10)

C.PopulateTenResults(unsafe.Pointer(&prslice[0]))

fmt.Println(prslice)

当然,硬编码的10只是为了简单起见;您可以将 的长度作为参数传递给 C。arr


查看完整回答
反对 回复 2022-09-12
?
largeQ

TA贡献2039条经验 获得超7个赞

可以将指针传递到切片中的第一个元素以及切片的长度,以C++并将其视为 C 样式数组。


查看完整回答
反对 回复 2022-09-12
  • 2 回答
  • 0 关注
  • 101 浏览

添加回答

举报

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