首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将结构数组从C++传递给GO

将结构数组从C++传递给GO
EN

Stack Overflow用户
提问于 2021-07-01 04:52:37
回答 2查看 111关注 0票数 1

我试图获得从C++到golang的tensorflow框预测数组,但无论我做什么都做不到。我有一个GO程序,它调用一个使用cgo在C++中执行tensorflow检测的函数。这一切都有效,我可以在C++中得到预测结果。问题是将这些预测作为100个结构的数组传输到GO中,每个结构包含一个预测。

我可以在GO中设置一个指针,并使用这个指针地址在C++中设置一个结构。代码如下所示。

我想在C++中设置一个结构数组,并在GO中检索这个数组。我认为使用与前面相同的指针地址并将其用作我的C++数组的地址应该很容易。然后,我可以从GO中的指针恢复结构。有人有解决这个问题的办法吗?

代码语言:javascript
运行
复制
type PredictResult struct {
    Loc   [4]float32
    Score int
    Label int
}

var predictions PredictResult
predictions_ptr := unsafe.Pointer(&predictions)
C.LIB_predict(predictions_ptr)

fmt.Println("GO predictions; ", predictions)

bridge.hpp

代码语言:javascript
运行
复制
struct PredictResult{
    float Loc[4];
    int64_t Score;
    int64_t Label;
};

void LIB_predict(void* predictions);

bridge.cpp

代码语言:javascript
运行
复制
void LIB_predict(void* predictions){

PredictResult *p = (PredictResult*)predictions;
    p->Score = 6;
    p->Label = 95;
}

打印:

代码语言:javascript
运行
复制
GO predictions;  {[0 0 0 0] 6 95}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-07-01 07:46:34

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

代码语言:javascript
运行
复制
// #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)
}

您最感兴趣的是如何将getTenResults的结果转换为适当结构类型的Go切片。这是在使用technique recommended on the Go wiki

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

作为另一种选择,如果您希望在Go端分配切片并传递一个指向C的指针来填充,您可以这样做:

代码语言:javascript
运行
复制
// 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"

然后在Go do中:

代码语言:javascript
运行
复制
prslice := make([]PredictResult, 10)
C.PopulateTenResults(unsafe.Pointer(&prslice[0]))
fmt.Println(prslice)

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

票数 2
EN

Stack Overflow用户

发布于 2021-07-01 06:19:56

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68201487

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档