How to send uint8_t array from C to GO

Hello ,

I am beginner in go :slight_smile: , and i would like to send uint8_t array from C to GO, but when i send my array like pointer, i don’t know how i can read it and save it in GO like byte[] array type .
Here is my code :

package main
/*
#include <stdint.h>

uint8_t Plaintext[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};

uint8_t * send_data( )
   {
     return  Plaintext;
   }

*/
import "C"
import "unsafe"
import "fmt"

func main() {

    data := [16]byte{}
    p := C.send_data()
    //already try  data = C.send_data()
    fmt.Println(p)
    data = p // don't know how do this ?

}

The objectif is to have data byte array in go like :

data[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}

I try lot of solution, but every time i have log that say " cannot use (func literal)() (type *_Ctype_uchar) as type"uint8" or “byte” …

Thanks guys for your help !

2 Likes

Hi, Jawad,

The returned value from your send_data function has the Go type, *_Ctype_uchar which cannot be assigned to a [16]byte array. There are a few ways to do this. One way is to use the unsafe.Pointer type with the C.GoBytes helper function:

package main

/*
#include <stdint.h>

uint8_t Plaintext[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};

uint8_t * send_data( )
   {
     return  Plaintext;
   }

*/
import "C"
import "unsafe"
import "fmt"

func main() {

    data := [16]byte{}
    p := C.GoBytes(unsafe.Pointer(C.send_data()), 16)
    fmt.Println(p)
    copy(data[:], p)
    fmt.Printf("%T: %v\n", data, data)
}

I think this is the right way to do this. An alternative is to cast that unsafe.Pointer and cast it right to *[16]byte:

package main

/*
#include <stdint.h>

uint8_t Plaintext[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};

uint8_t * send_data( )
   {
     return  Plaintext;
   }

*/
import "C"
import "unsafe"
import "fmt"

func main() {

    data := [16]byte{}
    p := C.send_data()
    fmt.Println(p)
    p16byte := *((*[16]byte)(unsafe.Pointer(p)))
    data = p16byte
    fmt.Printf("%T: %v\n", data, data)
}
3 Likes

Hello @skillian ,

Thanks for your reply, i use the seconde solution like you describe and it’s work fine.

I have just another question on the same subject ! do you know how can i put variable into the bound of array ?

Relpace this line : 
p16byte := *((*[16]byte)(unsafe.Pointer(p)))

By : 
 int lens_var = 16
 p16byte := *((*[lens_var]byte)(unsafe.Pointer(p)))

But it’s not working, because it’s not already compiled, i try also to use slice but also that doesn’t work:

int lens_var = 16
var type_var= make([]byte, lens_var )
p16byte := *((*type_var)(unsafe.Pointer(p)))

Maybe i ignore some details !!!

Thanks again

2 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.