Wrapping array of booleans

Hi!

I am currently working on wrapping an RTK filter which has a bool * property along with a setter. The wrapped filter properly compiles but the method, when called from a Python script, produces an error (something like the method expects a bool *). I call it by passing a standard Python array (like [True, False, True]) as a parameter. Wrapping C arrays works correctly for other data types, such as int * or float *, but seems broken for bool *.

I tried to look at ITK source code in order to figure out how C arrays are wrapped, but I could not understand, and as far as I searched ITK never wraps bool *. I also tried to replace my bool * by a std::vector<bool> and it made the wrapped filter work.

I thus have several questions:

  • According to ITK development guidelines, is it alright to wrap a std::vector<bool> instead of a bool *? (RTK tries to stick as much as possible to ITK guidelines.)
  • Is there something to modify in ITK which would enable bool * to be properly wrapped?
  • Is there any significant difference in wrapping a std::vector instead of a standard C array?

Sorry if the questions seem basic, I am far from being a swig expect.

Thank you very much!

2 Likes

@matt.mccormick can best answer this question, but probably in about two weeks when he gets back to the office.

Not tested, but should be easy to add a couple of lines here:

%array_functions(bool, BArray);
%array_class(bool, BArrayClass);
2 Likes

Hi,

Thank you for your kind replies!
I have tried to implement @phcerdan’s solution, and recompiled everything from scratch, but the error message remains identical:
TypeError: in method '...', argument 2 of type 'bool *'

I’m still stuck with this issue, as my understanding of Swig is very limited. Any tip would be greatly appreciated! Thank you very much.

Hi @acoussat!

While there is already some std::vector< bool > wrapping support in ITK, we should use it with caution and prefer alternatives like std::vector< unsigned char > or other container types when possible. This is because C++ has a special optimization for std::vector< bool >,where a single bit is used to store every element. But, other tools in the Python ecosystem, like Cython and NumPy use unsigned char. The ITK Python wrapping aims to work seamlessly with NumPy and friends.

That said, to instantiate a vector< bool >:

import itk
v = itk.vector.B()

bool *, and other raw pointers, should be avoided when wrapping in favor of itk or std containers because memory management is easier – the wrapped item will clean up its memory when it is destroyed.

2 Likes