dongxun7301 2015-02-17 16:31
浏览 147
已采纳

在Go(golang)和C ++之间交换数据结构(数组)

I'm trying to connect a C++ library to an appserver written in Go. The goal is that both the C++ library and the appserver are working on a common data structure, which means that:

  1. The Go appserver can access an array created by the C++ library.
  2. The C++ library can work on an array created by the Go appserver.

I was playing a little bit around with cgo and connecting C++ and everything worked so far... However, when it comes to exchanging pointers to data structures I'm lost. What I tried so far:

//c++ library header: xyz.h

#include <stdlib.h>

class CppLib {
 public:
  CppLib(unsigned int input);

  int * CreateArray();
};

//C++ library implementation: xyz.cpp
#include "xyz.h"

CppLib::CppLib(unsigned int input) {
    _input = input;
  }

int * CppLib::CreateArray() {
    int values = 5;
    int * myPointer = new int [values];
    for (unsigned i = 0; i < values; ++i) {
        myPointer[i] = i;
    }
    return myPointer;
}

The interface implementation looks like:

//interface.h

int * CCreateArray();

//interface.cc
#include "../lib/xyz.h"

extern "C" {

  int * CCreateArray() {
    CppLib lib(1);
    return lib.CreateArray();
  }
}

Finally the go implementation looks like:

package cgo_lib

// #cgo CFLAGS: -I../lib
// #cgo LDFLAGS: -L../lib -linterfacelib
// #include "interface.h"
import "C"

func GoCreateArray() *int {
    return *int(C.CCreateArray())
}

When compiling I receive the following error:

# cgo_lib
../cgo_lib/cgo_lib.go:13: cannot convert _Cfunc_CCreateArray() (type *C.int) to type int
../cgo_lib/cgo_lib.go:13: invalid indirect of int(_Cfunc_CCreateArray()) (type int)

So my question is: How to exchange pointers to data structures between C++ and Go. Above I just described the way from C++ to GO, but I'm also interested in the other way round.

Thanks a lot for your help in advance.

  • 写回答

1条回答 默认 最新

  • dsc80135 2015-02-17 17:44
    关注

    This here:

    return *int(C.CCreateArray())
    

    can be written as

    return *((int)(C.CCreateArray()))
    

    You're derreferencing an int, which results in:

    invalid indirect of int(_Cfunc_CCreateArray()) (type int)
    

    And inside that statement, observing only this part:

    (int)(C.CCreateArray())
    

    You're trying to convert an *C.int to an int, which won't work cause the first is a pointer and the second not.

    Beyond that and the memory-management trouble that @tadman mentions in the comments of your question, Go does not represent arrays as pointers to their first element as C does.

    If you want to share ints you'll have to be specific about their width: an int in Go has an arch-dependent width, as well as a C int.

    Read more about CGO: http://golang.org/cmd/cgo/

    Once you have fixed all these problems, you'll have to proceed something like this:

    s := make([]int32, 0, 0)
    
    h := (*reflect.SliceHeader)((unsafe.Pointer)(&s))
    
    h.Data, h.Len, h.Cap = P, L, L // see below
    
    s = *(*[]int32)(h)
    

    where P is a Go uintptr to your array, which you created in C++ and L is the length of the array as a Go int

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 请问一下这个运行结果是怎么来的
  • ¥15 这个复选框什么作用?
  • ¥15 单通道放大电路的工作原理
  • ¥30 YOLO检测微调结果p为1
  • ¥20 求快手直播间榜单匿名采集ID用户名简单能学会的
  • ¥15 DS18B20内部ADC模数转换器
  • ¥15 做个有关计算的小程序
  • ¥15 MPI读取tif文件无法正常给各进程分配路径
  • ¥15 如何用MATLAB实现以下三个公式(有相互嵌套)
  • ¥30 关于#算法#的问题:运用EViews第九版本进行一系列计量经济学的时间数列数据回归分析预测问题 求各位帮我解答一下