Cgo - How to convert string to C fixed char array

I am trying to instantiate a C struct inside my Go code. The structure is defined as follows (in an external library which I cannot change):

typedef struct {
    char field1[256];
} S1

      

In go, I did this:

func myfunc(mystr string){
    // We need to convert mystr from string to char array
    cStr := C.CString(mystr)
    defer C.free(unsafe.Pointer(cStr)

    // Should work now
    s1 := &C.S1{field1: cStr}

    // Do something with s1...
}

      

But it doesn't compile because:

cannot use cStr (type * C.char) as type [256] C.char in field value

I tried to force ([256] C.char) (cStr) but it obviously doesn't work either.

Is there a way to achieve what I am trying to do?

+3


source to share


2 answers


The simplest solution is to change the structure field definition to char -pointer, which is pretty standard for strings in C:

typedef struct {
    char *field1;
} S1

      

A more complex solution would be [1] :



arr := [256]C.char{}

for i := 0; i < len(mystr) && i < 255; i++ { // leave element 256 at zero
    arr[i] = C.char(mystr[i])
}

s1 := &C.S1{field1: arr}

      

[1] The code is untested and cannot compile on this workstation.

+3


source


Unfortunately, there are no convenience methods to be treated [size]C.char

as strings in Go (I think I saw a suggestion to add this at some point, though ...)

In my code, instead of referring directly to it, I decided to manually write the string to the structure as needed with some types

func strCopy(dest *[maxTextExtent]C.char, src []byte) {
    for i, c := range src {
        dest[i] = C.char(c)
    }
    // This is C, we need to terminate the string!
    dest[len(src)] = 0
}

      



And the way I used it, which is much less secure,

s1 := &C.S1{
    field1: *(*[256]C.char)(unsafe.Pointer(cStr)),
}

      

+2


source







All Articles