Search code examples
javacjava-native-interfaceswig

SWIG turns 'bool' C type into a SWIGTYPE, even when including stdbool.h in interface file


SWIG generated a SWIGTYPE_p__Bool to use when c functions returned bool types. This seems incorrect.

Example C function returning bool:

bool
bitwuzla_sort_is_equal(const BitwuzlaSort *sort0, const BitwuzlaSort *sort1)
{
  BZLA_CHECK_ARG_NOT_NULL(sort0);
  BZLA_CHECK_ARG_NOT_NULL(sort1);
  BZLA_ABORT(sort0->d_bzla != sort1->d_bzla,
             "given sorts are not associated with the same solver instance");

  BzlaSortId bzla_sort0 = BZLA_IMPORT_BITWUZLA_SORT(sort0);
  BzlaSortId bzla_sort1 = BZLA_IMPORT_BITWUZLA_SORT(sort1);
#ifndef NDEBUG
  Bzla *bzla = BZLA_IMPORT_BITWUZLA(sort0->d_bzla);
  assert(bzla_sort_is_valid(bzla, bzla_sort0));
  assert(bzla_sort_is_valid(bzla, bzla_sort1));
#endif

  return bzla_sort0 == bzla_sort1;
}

The generated Java wrapper code:

  public static SWIGTYPE_p__Bool bitwuzla_sort_is_equal(SWIGTYPE_p_BitwuzlaSort sort0, SWIGTYPE_p_BitwuzlaSort sort1) {
    return new SWIGTYPE_p__Bool(bitwuzlaJNI.bitwuzla_sort_is_equal(SWIGTYPE_p_BitwuzlaSort.getCPtr(sort0), SWIGTYPE_p_BitwuzlaSort.getCPtr(sort1)), true);
  }

The interface file:

%module bitwuzla
%include "typemaps.i"
%include "arrays_java.i"

%{
#include "bitwuzla.h"
%}

%apply size_t *OUTPUT { size_t *size };
%inline %{
const BitwuzlaTerm ** bitwuzla_get_unsat_assumptions(Bitwuzla *bitwuzla, size_t *size);
%}

typedef struct Bitwuzla Bitwuzla;

%include "bitwuzla.h"

%include <carrays.i>
%array_functions(BitwuzlaTerm *, bt_array);


%include <stdbool.h>
%include <stdio.h>
%include <stddef.h>
%include <stdarg.h>
%include <stdint.i>

Example usage in Java:

SWIGTYPE_p_BitwuzlaSort bvsort = bitwuzla.bitwuzla_mk_bv_sort(bzla, 1);
SWIGTYPE_p_BitwuzlaTerm var = bitwuzla.bitwuzla_mk_const(bzla, bvsort, "x" + 1);
SWIGTYPE_p_BitwuzlaSort varSort = bitwuzla.bitwuzla_term_get_sort(var);
assert(bitwuzla.bitwuzla_sort_is_equal(bvsort, varSort));

The command for generating the library: swig -DSWIGWORDSIZE64 -includeall -I/usr/lib/gcc/x86_64-linux-gnu/11/include -I/usr/include -java bitwuzla.i

I tried adding stdbool.h to the interface file, but this didn't resolve the problem. Furthermore, there is a SWIGTYPE_p_bool type, which is never used. This problem could probably be solved using typemaps, but this seems like some misconfiguration or misunderstanding on my end.


Solution

  • In C99, bool is a strange beast, it is a #define - if you are compiling in C++ mode it expands to C++ bool otherwise it expands to the new primitive type _Bool that exists only in C99. This type is not currently recognized by SWIG as a primitive type.

    Just map it to int and you will be fine:

    %apply int { _Bool };
    

    Your functions will return/expect 0/1.

    or

    You can compile in C++ mode. The C++ bool is recognized by SWIG.

    or

    Look at /usr/local/share/swig/x.x.x/java/java.swg and copy one line of each typemap (jni, jtype...) and map it to Java "bool".