baz_ptr.b undefined (type *GoBaz has no field or method b)

297 views
Skip to first unread message

Ami Ladani

unread,
Jul 22, 2021, 5:53:26 PM7/22/21
to golang-nuts
Hi all,

I am trying to access members of a C struct from go. Compiler is showing structure's members are undefined. I have attached my code and the error message below. 

Please have a look and help if you can.

$CGO_ENABLED=1 go run main.go cfuncs.go
# command-line-arguments
./main.go:18:44: baz_ptr.b undefined (type *GoBaz has no field or method b)
./main.go:19:44: baz_ptr.f undefined (type *GoBaz has no field or method f)


//c_header.h
typedef void (*cb)(void* qux, int status, void *command_data, void *cb_data);
typedef struct{
  int a;
  int b;
} Foo;

typedef struct{
  char* ch;
  cb callback;
} Bar;

typedef struct{
  Foo* f;
  Bar* b;
} Baz;
//--------------------------------

//cfuncs.go
package main
/*
#include<c_header.h>
#include <stdlib.h>

Baz* allocateBaz(){
     Baz* baz = malloc(sizeof(Baz));
     Bar* bar = malloc(sizeof(Bar));
     Foo* foo = malloc(sizeof(Foo));
     baz->f = foo;
     baz->b = bar;
     return baz;
}
*/
import "C"
//-------------------------------------------------

//main.go
package main/*
#include<c_header.h>
extern Baz* allocateBaz();
*/
import "C"
import "unsafe"
type GoBaz C.struct_Baz
type GoBar C.struct_Bar
type GoFoo C.struct_Foo
func main() {
  baz_ptr := (*GoBaz)(unsafe.Pointer(C.allocateBaz()))
  bar_ptr := (*GoBar)(unsafe.Pointer(baz_ptr.b))
  foo_ptr := (*GoFoo)(unsafe.Pointer(foo_ptr.f))

//--------------------------------
Thanks in advance!
Regards
Ami

Ian Lance Taylor

unread,
Jul 22, 2021, 6:13:19 PM7/22/21
to Ami Ladani, golang-nuts
Interesting. I think that has to do with the fact that you are using
two different Go files that both #include <c_header.h>. <c_header.h>
uses typedef to define anonymous structs. The fact that the header is
being included twice in the same package seems to be causing cgo to
generate two different Go structs, one for each .go file. And then it
can't figure out the definition of the Go struct, so you get this
error.

This is probably a bug in cgo, so feel free to file an issue at
https://golang.org/issue.

You can probably make progress by combining the .go files so that you
only have a single import "C" with a #include <c_header.h>.

Ian

Ami Ladani

unread,
Jul 23, 2021, 1:39:39 PM7/23/21
to golang-nuts
Hi Ian,
I tried to merge both go files as you suggested and it is showing same error as the previous one. 
Following is the code. Also, I would like to mention that I am using Go1.15 linux/amd64.

$CGO_ENABLED=1 go build .
# _/home/ami.ladani/Downloads/experiment
./main.go:22:44: baz_ptr.b undefined (type *GoBaz has no field or method b)
./main.go:23:44: baz_ptr.f undefined (type *GoBaz has no field or method f)

// c_header.h
typedef void (*cb)(void* qux, int status, void *command_data, void *cb_data);
typedef struct{
  int a;
  int b;
} Foo;
typedef struct{
  char* ch;
  cb callback;
} Bar;
typedef struct{
  Foo* f;
  Bar* b;
} Baz;
Baz* allocateBaz(){
  Baz* baz = malloc(sizeof(Baz));
  Bar* bar = malloc(sizeof(Bar));
  Foo* foo = malloc(sizeof(Foo));
  baz->f = foo;
  baz->b = bar;
  return baz;
}

//main.go
package main
/*
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "c_header.h"

*/
import "C"
import "unsafe"
type GoBaz C.struct_Baz
type GoBar C.struct_Bar
type GoFoo C.struct_Foo

func main() {
  baz_ptr := (*GoBaz)(unsafe.Pointer(C.allocateBaz()))
  bar_ptr := (*GoBar)(unsafe.Pointer(baz_ptr.b))
  foo_ptr := (*GoFoo)(unsafe.Pointer(baz_ptr.f))


Thanks!
Ami

Ian Lance Taylor

unread,
Jul 23, 2021, 3:01:00 PM7/23/21
to Ami Ladani, golang-nuts
Ah, you're right, I missed something. The C code says

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

The Go code says

type GoFoo C.struct_Foo

That's not right. In Go C.struct_Foo refers to the type defined in C
as "struct Foo". But there is no such type in your C header. There
is only the typedef of an anonymous struct to Foo. The way to refer
to that in Go is "C.Foo". If I remove the "struct_" from your Go code
then it works for me.

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...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/b3233044-7f3a-46c6-8d59-58a7f1835109n%40googlegroups.com.

Ami Ladani

unread,
Jul 24, 2021, 12:59:11 AM7/24/21
to golang-nuts
Hi Ian,
It is working now. Thank you so much for a quick response. 

Ami 
Reply all
Reply to author
Forward
0 new messages