Thanks Ian!

My C's a bit rusty, I'd expected I'd have to explicitly allocate some 
memory for rLimits, similar to askedHosts, turns out that isn't required 
after all and your suggestion of setting element by element is working like 
a charm!

Thanks again,

Mark

On Tuesday, January 28, 2020 at 3:21:55 PM UTC, Ian Lance Taylor wrote:
>
> On Tue, Jan 28, 2020 at 4:44 AM mark mellar <radiat...@gmail.com 
> <javascript:>> wrote: 
> > 
> > Hi Folks, I'm having some trouble instantiating a C struct from a 3rd 
> party API. 
> > 
> > I'm not sure if this is more a C question or a Go question, details in 
> the code below, any help would be much appreciated! 
> > 
> > M 
> > 
> > // This non-compiling example demonstrates an issue I'm having 
> integrating a 3rd party C api with my Go code 
> > // The comment preceding 'import "C"' constitutes C code which is 
> interpreted as a header when compiling. 
> > // 'api_struct' represents the 3rd party struct I'm attempting to 
> instantiate and populate in my Go Code 
> > //    we cannot make changes to this struct 
> > // other c functions in the comment are helper functions I've written to 
> instantiate certain C types 
> > 
> > // The go code defines an array of strings and an array of ints. For 
> each of these arrays a helper 
> > // function is called to create a C array of the C equivalent type 
> before populating that array. 
> > // Once C arrays have been populated they are assigned to fields in the 
> a new api_struct. 
> > 
> > // This method works fine for the string array, but compile fails when 
> we get to the int array 
> > // This is because makeIntArray returns *_Ctype_int but 
> api_struct.rLimits expects [12]_Ctype_int. Here's the error... 
> > // cannot use cInts (type *_Ctype_int) as type [12]_Ctype_int in field 
> value 
> > 
> > // I'd like to modify makeIntArray to return a [12]_Ctype_int but I 
> can't seem to find the right syntax to achieve this 
> > package main 
> > 
> > /* 
> > #define  ARRLEN 12 
> > #include <stdlib.h> 
> > 
> > struct api_struct { 
> > char    **askedHosts; 
> > int     rLimits[ARRLEN]; 
> > }; 
> > 
> > static char**makeCharArray(int size) { 
> >         return calloc(sizeof(char*), size); 
> > } 
> > 
> > static void setArrayString(char **a, char *s, int n) { 
> >         a[n] = s; 
> > } 
> > 
> > static void freeCharArray(char **a, int size) { 
> >         int i; 
> >         for (i = 0; i < size; i++) 
> >                 free(a[i]); 
> >         free(a); 
> > } 
> > 
> > static int*makeIntArray() { 
> >         int* p = malloc(sizeof(p) * ARRLEN); 
> >         return p; 
> > } 
> > 
> > static void setArrayInt(int *a, int s, int n) { 
> >         a[n] = s; 
> > } 
> > 
> > static void freeIntArray(int *a, int size) { 
> >         free(a); 
> > } 
> > 
> > 
> > */ 
> > import "C" 
> > import "fmt" 
> > 
> > func main() { 
> > goHosts := []string{"host1", "host2", "host3"} 
> > cHosts := C.makeCharArray(C.int(len(goHosts))) 
> >         for i, s := range goHosts { 
> >                 C.setArrayString(cHosts, C.CString(s), C.int(i)) 
> >         } 
> > 
> > goLimits := []int{1,2,3,4,5,6,7,8,9,10,11,12} 
> > cInts := C.makeIntArray() 
> >         for i, s := range goLimits { 
> >                 C.setArrayInt(cInts, C.int(s), C.int(i)) 
> >         } 
> > 
> > s := C.struct_api_struct{ 
> > askedHosts: cHosts, 
> > rLimits: cInts, 
> > } 
> > fmt.Printf("%+v\n", s) 
> > } 
>
>
> The easy, and likely more efficient, way is to just set the rLimits 
> field element by element. 
>
> There is no safe way to convert from a *C.int to a [12]C.int in Go. 
> You can do it easily enough using unsafe. 
>
> a := *(*[12]C.int)(unsafe.Pointer(p)) 
>
> This is of course only safe if p does in fact point to 12 C.int values. 
>
> Ian 
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/7470e567-a05d-4330-a095-24ef995126d0%40googlegroups.com.

Reply via email to