Helin Wang
Helin Wang

Reputation: 4202

Does passing a slice to golang from c do a memory copy?

I need to pass a big chunk for float32 (or byte) from C to a go library.

Here is the code:

package main

import (
        "C"
        "fmt"
)

//export PrintInt                                                                                                     
func PrintInt(x []float32) {
        fmt.Println(x)
}

func main() {}

After compile it with go build -buildmode=c-archive foo.go

I got foo.h, here of a part of it:

typedef GoInt64 GoInt;
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;

#endif

/* End of boilerplate cgo prologue.  */

#ifdef __cplusplus
extern "C" {
#endif


extern void PrintInt(GoSlice p0);

#ifdef __cplusplus
}
#endif

You can see that type GoSlice in foo.h holds a pointer to the data (void *data). So does the implementation of PrintInt in foo.h do an implicit copy of that data?

Upvotes: 1

Views: 1246

Answers (1)

Helin Wang
Helin Wang

Reputation: 4202

I tried to modify the data from go side, it is reflected in C. So they share same memory.

foo.go:

package main

import (
    "C"
    "fmt"
)

//export PrintInt
func PrintInt(x []float32) {
    fmt.Println(x)
    for i := range x {
        x[i] = -float32(i)
    }
}

func main() {}

foo.c:

#include <stdio.h>

#include "foo.h"

int main() {
  float bar[32];
  for(int i = 0; i < 32; i++) {
    bar[i] = i;
  }

  GoSlice s;
  s.data = (void*)bar;
  s.len = 32;
  s.cap = 32;
  PrintInt(s);

  for(int i = 0; i < 32; i++) {
    printf("%f ", bar[i]);
  }

  return 0;
}

With command:

go build -buildmode=c-archive foo.go
cc foo.c foo.a -o 123 && ./123

I got output:

[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31] -0.000000 -1.000000 -2.000000 -3.000000 -4.000000 -5.000000 -6.000000 -7.000000 -8.000000 -9.000000 -10.000000 -11.000000 -12.000000 -13.000000 -14.000000 -15.000000 -16.000000 -17.000000 -18.000000 -19.000000 -20.000000 -21.000000 -22.000000 -23.000000 -24.000000 -25.000000 -26.000000 -27.000000 -28.000000 -29.000000 -30.000000 -31.000000

Upvotes: 3

Related Questions