0

I need to pass slice of structure objects to C function. C function expects pointer to struct objects I followed How to pass pointer to slice to C function in go. I tried to replicate the original requirement in sample. In sample I am getting

could not determine kind of name for C.f

I am C programmer, just started working on Go-module of project. Can someone correct the below sample or provide a sample to pass go slice to C-function (C-code takes pointer to structure or double pointer (whatever is appropriate))

here is my sample code

package main
/*
#include <stdio.h>
#include "cgoarray.h"
struct test {
   int a;
   int b;
};
int f(int c, struct test **s) {
    int i;
    printf("%d\n", c);
    for (i = 0; i < c; i++) {
        printf("%d\n", s[i].a);
    }
    c = (c) + 1;
    return 1;
}
*/
import "C"
import "unsafe"

type struct gotest{
   a int
   b int
}

func go_f(harray ...gotest) {
        count := len(harray)
    c_count := C.int(count)
    cArray :=(*C.struct_test)(C.malloc(C.size_t(c_count) *8));

        // convert the C array to a Go Array so we can index it
        a := (*[1<<30 - 1]*C.struct_test)(cArray)
        for index, value := range harray {
            a[index] = value
        }

        err := C.f(10, (**C.struct_test)(unsafe.Pointer(&cArray)))
        return 0
}

func main(){
        t :=gotest{10,20}
        t1 :=gotest{30,40}
        t2 :=gotest{50,60}
        fmt.Println(t,t1,t2)
   go_f(t1,t2,t3)
}


learner
  • 55
  • 5
  • "tried to solve problem, but failed to do so" is not a problem statement. What exactly didn't work, what did you expect to happen, and what else did you try? It would help to crate a [mre] showing the issue you are having. – JimB Apr 19 '21 at 14:45
  • @JimB I edited the original post – learner Apr 19 '21 at 15:03
  • Your first mistake is that `import "C"` must be on the line immediately after a C preamble. See the very first part of the [`cgo` documentation](https://golang.org/cmd/cgo/#hdr-Using_cgo_with_the_go_command) – JimB Apr 19 '21 at 15:06
  • Sorry for basic mistake. Corrected it now. – learner Apr 19 '21 at 15:12

1 Answers1

0

Run this main.go:

package main

/*
#include <stdio.h>
#include <stdlib.h>

typedef struct {
    int a;
    int b;
} Foo;

void pass_array(Foo **in, int len) {
    for(int i = 0; i < len; i++) {
        printf("A: %d\tB: %d\n", (*in+i)->a, (*in+i)->b);
    }
}
*/
import "C"

import (
    "unsafe"
)

type Foo struct{ a, b int32 }

func main() {
    foos := []*Foo{{1, 2}, {3, 4}}
    C.pass_array((**C.Foo)(unsafe.Pointer(&foos[0])), C.int(len(foos)))
}

With:

GODEBUG=cgocheck=0 go run main.go
derkan
  • 475
  • 4
  • 5
  • 1
    go run main.go is causing panic error panic: runtime error: cgo argument has Go pointer to Go pointer goroutine 1 [running]: main.main.func1(0xc000030760) PRACTICE/GOLANG/sample.go:29 +0x79 main.main() PRACTICE/GOLANG/sample.go:29 +0xc7 I am not sure if I can use cgocheck=0 in production code – learner Apr 19 '21 at 15:56