SWIG-generated Go wrapper mishandling(?) pointers to pointers to structs

48 views
Skip to first unread message

mark mellar

unread,
Apr 17, 2020, 10:34:00 AM4/17/20
to golang-nuts

Hi folks,

We're integrating a Go program with a 3rd party C api, but are getting some odd results when working with pointers to pointers to structs. A model of the header file looks a bit like this...

//mytest.h

typedef struct Books {
 
char title[50];
 
char author[50];
 
char subject[100];
 
int book_id;
}

Book; extern void initbook(Book** b);

With a model implementation like this...

//mytest.c
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

typedef struct Books {
 
char title[50];
 
char author[50];
 
char subject[100];
 
int book_id;
} Book;

void initbook(Book** b){ *b = malloc(sizeof(Book));
 strcpy
( (*b)->title, "A Book Title");
}

We've tried wrapping the API with a very simple SWIG file which looks like this...

%module mytest %{
 
#include "./mytest.h"
%}
%include "./mytest.h"

And call it from a Go main function like this...

//main.go

package main
import "fmt"
import "mytest"
func main
() {
 bookPtr
:= mytest.NewBook()
 mytest
.Initbook(bookPtr)
 fmt
.Printf("title: '%s'\n", bookPtr.GetTitle())
}

However, we've found when we run this we the value being returned from GetTitle() is garbled....

> go run ../main.go
title: '??'

Digging in to the generated C code we found that editing the Book constructor to return Book** rather than Book*, and then modifying the GetTitle function to receive a Book** instead of Book* things started working as expected.

Any hints on how we might configure SWIG to generate a version of the code which works for us. without us having to hack what it generates?

Thanks!

Mark

Ian Lance Taylor

unread,
Apr 17, 2020, 12:59:25 PM4/17/20
to mark mellar, golang-nuts
Since this is a C API, I suggest that you use cgo. https://blog.golang.org/cgo.

If you want to use SWIG, you'll likely need to use directives like
%gotype to teach SWIG how the C type should be represented in Go. It
seems clear that SWIG is getting confused, as from what you wrote
above it seems that the Go code ought to be mytest.Initbook(&bookPtr).

Ian
Reply all
Reply to author
Forward
0 new messages