Pass a populated GO structure from GO source file to C : ctogo

Am trying to send a GO structure from from GO code to a C code and access the content of GO structure in C.
I was able to pass a GO int from GO code to C and access the GO int in C and also was able to modify, but am facing issues in passing a GO structure to C. Below is the code snippet.

go_func.go

package main

import (
    /*
        #include "cmain.h"
    */
    "C"
    "fmt"
)

type test struct {
    first_name string
    last_name  string
}

func main() {
    var p test
    p.first_name = "Hello"
    p.last_name = "How are you"
    C.cmain(C.test(&p))
}

cmain.h

typedef struct {
    char first_name[100];
    char last_name[100];
}test;

void cmain(test*);

cmain.c

#include <stdio.h>
#include "cmain.h"
#include "_cgo_export.h"

  void cmain(test *value) {
    printf("first_name:%s\n", value->first_name);
    printf("last_name:%s\n", value->last_name);
}

I get error when i try the above,
Adding to the above issue, i have a doubt, cant i have a single structure in GO and pass the same structure to C, is it required to have the similar replica of the GO structure even in C ?

Go strings are nothing like C strings. See https://golang.org/cmd/cgo/ for functions to convert between the two. You also can’t pass any Go pointers into the C world. Generally you’ll have to manage allocations and copies at the boundary.

Thank you @calmh, can you please let me know what is the problem in the code that i have written ?

You’re trying to convert a

type test struct {
    first_name string
    last_name  string
}

to a

typedef struct {
    char first_name[100];
    char last_name[100];
}test;

by C.cmain(C.test(&p)).

This is impossible because a Go string looks nothing like a C char[100] (nor a *char for that matter).

Which, I suspect, is what the error that you’re not showing us is also telling you.

What you need to do is malloc a new C.test, use the conversion functions to copy and convert the strings, and pass the pointer to that into C.

Can you please tell me what do you mean by malloc a new C.test. I need to copy the contents of GO Structure to C Structure, so for that i have used C.CStrings and C.GoStrings, but not able to find any success, I have re iterated the code below.

I want to copy contents of GOLang structure to C Structure.
Here i want the populated GO Struct (type test struct) to be copied to C structure test_c.

Have put the following logic. I have accessed C structure test_c in go file, as C.test_c, and tried to copy the content of test struct to C.test_c (p_c) by using C.GoString, but when ever i try to do this i get this error

Can anyone let me know what is the mistake that am doing, is there a better method to achive the same ?

./go_structure.go:30: cannot use _Cfunc_CString(p_go.a) (type *C.char) as type [10]C.char in assignment
./go_structure.go:31: cannot use _Cfunc_CString(p_go.b) (type *C.char) as type [10]C.uchar in assignment

Below is the code,

go_stucture.go

package main

import (
    /*
        #include "cmain.h"
    */
    "C"
    "fmt"
    "unsafe"
)

type test struct {
    a string
    b string
}

func main() {

    var p_go test
    var p_c C.test_c
    p_go.a = "ABCDEFGHIJ"
    p_go.b = "QRSTUVXWYZ"

    //fmt.Println(unsafe.Sizeof(p_c.a))

    fmt.Println("In GO code\n")
    fmt.Println("GO code structure Member:a=%s", p_go.a)
    fmt.Println("GO code structure Member:b=%s", p_go.b)

    p_c.a = C.GoString(p_go.a)
    p_c.b = C.GoString(p_go.b)

    fmt.Println("Call C function by passing GO structure\n")
    C.cmain((*C.test_c)(unsafe.Pointer(&p_c)))
}

cmain.c

#include <stdio.h>
#include "cmain.h"
#include "_cgo_export.h"

void cmain(test_c *value) {
    printf("Inside C code\n");
    printf("C code structure Member:a=%s\n", value->a);
    printf("C code structure Member:b=%s\n", value->b);
}

cmain.h

typedef struct {
    unsigned char a[10];
    unsigned char b[10];
}test_c;
void cmain(test_c* value);

It’s saying a *char is not a [10]char. C.GoString returns a char pointer, and that’s presumably what you should have in your C structure.

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