1

See code below and I will explain

int* Camera::retrieveDataPointerPerBuffer() {
    int cameraData [10] = {1,2,3,4,5,6,7,8,9,10};
    int* pSrc = cameraData;
    return cameraData; 
} //camera.cpp

The code above has int pointer pSrc pointing to array and then returned. This is a function in C++. Next, I am using SWIG to essentially wrap this C++ function, so that I can call it in Go. The following code demonstrates the function being called in Go.

func myCamera() {
    cam := camera.NewCamera()
    pSrc := cam.RetrieveDataPointerPerBuffer()

    for i := 0; i < 10; i++ {
        fmt.Println("%d", pSrc)
    }
} //main.go

Note: I know that I cannot iterate pointers in Go. But is there any way?

Output: 0

Problems: How do you access the arrays elements via pointer from C++ to Go? Additional Information: This is a simplified version of a larger project I am working on. I must return this pointer, I cannot return a vector.

Let me know if you need me to clarify anything for you.

Daniel Ramsey
  • 177
  • 1
  • 2
  • 9
  • Pass them as slices? – bipll Feb 20 '19 at 18:50
  • I must return the pointer from the function. I don't think slices is the correct play but would be happy to be proven wrong with example code. I think the issue could be how the pointer loses address as it goes from c++ to Go. Thanks for the reply – Daniel Ramsey Feb 20 '19 at 18:53
  • 1
    related questions: https://stackoverflow.com/questions/28925179/cgo-how-to-pass-struct-array-from-c-to-go, https://stackoverflow.com/questions/43330938/export-function-that-returns-array-of-doubles, https://stackoverflow.com/questions/36542385/casting-a-cgo-array-into-a-slice, https://stackoverflow.com/questions/47354663/access-c-array-of-type-const-char-from-go/47355217, https://stackoverflow.com/questions/42530538/how-to-pass-pointer-to-slice-to-c-function-in-go/42533858 – JimB Feb 20 '19 at 18:59
  • have you tried this? https://github.com/golang/go/wiki/cgo#turning-c-arrays-into-go-slices – JimB Feb 20 '19 at 19:02
  • @JimB all of your links are for C -> Go. Would my case be different if C++ -> Go? – Daniel Ramsey Feb 20 '19 at 19:30
  • Go only has a C interface (cgo), that's why you're using SWIG, to write the C interface for you. – JimB Feb 20 '19 at 19:37
  • @JimB Could you possibly provide a road map for tackling this problem? – Daniel Ramsey Feb 20 '19 at 19:56
  • @DanielRamsey: Can you explain which part you don't understand? If `pSrc` is a pointer, those 6 other examples all demonstrate accessing it as a go slice. – JimB Feb 20 '19 at 20:16
  • @JimB I dont understand how those 6 examples apply to my case because they all use C, not C++ – Daniel Ramsey Feb 20 '19 at 20:57
  • 1
    @DanielRamsey: Again, Go can only call C code, period. C++ code needs a C wrapper, which you're generating with SWIG. Besides that though, how would the `pSrc` pointer be any different between C and C++? They are both `int*`, and the memory layout would be identical. Try using the documented example first, and post any issues you encounter. – JimB Feb 20 '19 at 21:01
  • @JimB should I make the changes from from links you shared in the C wrapper the was generated by SWIFT? – Daniel Ramsey Feb 20 '19 at 22:06
  • 1
    @DanielRamsey: Sorry, I'm not following. If `pSrc` is the array pointer you want to access, then `pSrc` is what you want to convert to a slice using the technique shown. – JimB Feb 20 '19 at 22:10
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/188773/discussion-between-daniel-ramsey-and-jimb). – Daniel Ramsey Feb 20 '19 at 23:21
  • See also https://stackoverflow.com/questions/48756732/what-does-1-30c-yourtype-do-exactly-in-cgo, which explains the syntax of the slice conversion. – JimB Feb 21 '19 at 19:10

1 Answers1

2

@JimB Thanks for all of your resources. I figured it out and this seems to do the trick.

int* Camera::retrieveDataPointerPerBuffer() {
   int cameraData [10] = {1,2,3,4,5,6,7,8,9,10};
   int* pSrc = cameraData;
   return cameraData; 
} //camera.cpp

Below contains the changes that I made

func myCamera() { //For Goroutine
   cam := camera.NewCamera()
   pSrc := cam.RetrieveDataPointerPerBuffer()

   arraySize := 10
   slice := (*[1 << 30]C.int)(unsafe.Pointer(pSrc))[:arraySize:arraySize]

   fmt.Println(slice)
}

Output: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Follow Up Question: Would anyone mind explaining this line of code?

slice := (*[1 << 30]C.int)(unsafe.Pointer(pSrc))[:arraySize:arraySize]
Daniel Ramsey
  • 177
  • 1
  • 2
  • 9