Search code examples
cgolirc

cgo: use typedef struct in preamble


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)


Solution

  • 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.