cgo: use typedef struct in preamble

2.1k Views Asked by At

I'm trying to make Go bindings for lirc: https://github.com/inando/go-lirc

Simple functions like lirc_init() and lirc_deinit() work fine.

For the function 'lirc_command_init()' I need to use a struct type: https://github.com/inando/lirc/blob/master/lib/lirc_client.h#L334

typedef struct {
    char packet[PACKET_SIZE + 1];
    char buffer[PACKET_SIZE + 1];
    char reply[PACKET_SIZE + 1]; 
    int head;
    int reply_to_stdout;
    char* next;
} lirc_cmd_ctx;

I first tried something like this:

func lircCommandInit(format string, v ...interface{}) (todoctx string, err error) {
    var ctx C.struct_lirc_cmd_ctx
    cmd := C.CString(fmt.Sprintf(format, v...))
    ok, err := C.lirc_command_init(ctx, cmd)
    fmt.Println(ok, err)
    return
}

But this gives me this error: could not determine kind of name for C.lirc_command_init.
Not sure if the struct_ should be used for a type?
The ctx probably needs to be a pointer, but I always get the same error.

Then I tried with a wrapper, but this is giving me the error unknown type name 'lirc_cmd_ctx'

// #cgo LDFLAGS: -llirc_client
// #cgo CFLAGS: -I /usr/include/lirc
// #include <lirc_client.h>
//
// int lirc_command_init_custom(const char* msg)
// {
//     lirc_cmd_ctx ctx;
//     return -2;
// }
import "C"

What am I doing wrong here? How can I use that struct type in Go?

Update:
Not sure if this is related, but C.free also complains.

p := C.CString(prog)
defer C.free(unsafe.Pointer(p))

-> could not determine kind of name for C.free

Go version: go version go1.4 linux/amd64 (Vagrant on windows)

1

There are 1 best solutions below

1
JimB On BEST ANSWER

The could not determine kind of name for ... message is what you get when something isn't defined. In the case of C.free, add stdlib.h to your includes.

#include <stdlib.h>

The same goes for the other errors, except this is a case of importing the incorrect header, or the incorrect version of that header. Checking on a random ubuntu system, the lirc_client.h file is very different from the one you linked. Make sure you're using the correct version where the types are defined.