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

我试图从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 PredictResult

predictions_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);

桥.cpp


void LIB_predict(void* predictions){


PredictResult *p = (PredictResult*)predictions;

    p->Score = 6;

    p->Label = 95;

}

指纹:


GO predictions;  {[0 0 0 0] 6 95}


函数式编程
浏览 102回答 2
2回答

慕容708150

假设您的C函数返回数组为,并且假设您知道返回的数组的长度(在下面的示例中,我假设为10,但您可以用任何有效的方法替换它),这种方法应该有效:PredictResult*// #include <stdio.h>// #include <stdlib.h>//// typedef struct PredictResult {//&nbsp; &nbsp; &nbsp;float Loc[4];//&nbsp; &nbsp; &nbsp;int64_t Score;//&nbsp; &nbsp; &nbsp;int64_t Label;// } PredictResult;//// PredictResult* getOneResult() {//&nbsp; &nbsp;PredictResult* p = (PredictResult*)calloc(1, sizeof(PredictResult));//&nbsp; &nbsp;p->Score = 10;//&nbsp; &nbsp;p->Label = 99;//&nbsp; &nbsp;p->Loc[1] = 2.5;//&nbsp; &nbsp;p->Loc[3] = 3.5;//&nbsp; &nbsp;return p;// }//// PredictResult* getTenResults() {//&nbsp; &nbsp;PredictResult* parr = (PredictResult*)calloc(10, sizeof(PredictResult));//&nbsp; &nbsp;parr[0].Score = 10;//&nbsp; &nbsp;parr[0].Label = 99;//&nbsp; &nbsp;parr[0].Loc[1] = 2.5;//&nbsp; &nbsp;parr[0].Loc[3] = 3.5;////&nbsp; &nbsp;parr[4].Score = 44;//&nbsp; &nbsp;parr[4].Label = 123;//&nbsp; &nbsp;parr[4].Loc[1] = 12.25;//&nbsp; &nbsp;parr[4].Loc[3] = -40.5;//&nbsp; &nbsp;return parr;// }////import "C"type PredictResult C.struct_PredictResultfunc main() {&nbsp; &nbsp; p := C.getOneResult()&nbsp; &nbsp; if p == nil {&nbsp; &nbsp; &nbsp; &nbsp; log.Fatal("got nil")&nbsp; &nbsp; }&nbsp; &nbsp; pp := (*PredictResult)(p)&nbsp; &nbsp; fmt.Println(pp)&nbsp; &nbsp; parr := C.getTenResults()&nbsp; &nbsp; if parr == nil {&nbsp; &nbsp; &nbsp; &nbsp; log.Fatal("got nil")&nbsp; &nbsp; }&nbsp; &nbsp; pslice := (*[1 << 28]PredictResult)(unsafe.Pointer(parr))[:10:10]&nbsp; &nbsp; fmt.Println(pslice)}您最感兴趣的是如何将 的结果转换为相应结构类型的 Go 切片。这是采用Go维基上推荐的技术。getTenResults根据C函数的确切签名,您可能需要在部件中编写一个“桥接”函数,以提供方便Go的数据,但这是它的基本要点。import "C"或者,如果您希望在 Go 端分配切片并传入指向 C 的指针以进行填充,则可以执行以下操作:// void PopulateTenResults(void* arr) {//&nbsp; &nbsp;PredictResult* parr = (PredictResult*)arr;//&nbsp; &nbsp;parr[1].Score = 210;//&nbsp; &nbsp;parr[1].Label = 299;//&nbsp; &nbsp;parr[1].Loc[1] = 22.5;//&nbsp; &nbsp;parr[1].Loc[3] = 23.5;////&nbsp; &nbsp;parr[8].Score = 344;//&nbsp; &nbsp;parr[8].Label = 3123;//&nbsp; &nbsp;parr[8].Loc[1] = 312.25;//&nbsp; &nbsp;parr[8].Loc[3] = -340.5;// }////import "C"然后在围棋中做:prslice := make([]PredictResult, 10)C.PopulateTenResults(unsafe.Pointer(&prslice[0]))fmt.Println(prslice)当然,硬编码的10只是为了简单起见;您可以将 的长度作为参数传递给 C。arr

largeQ

可以将指针传递到切片中的第一个元素以及切片的长度,以C++并将其视为 C 样式数组。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java