I've been using SWIG successfully to build a wrapper interface to make my C++ libraries available in C#. Recently I exposed some boost::optional<>
objects and SWIG is having problems with them. Is there a standard way to deal with this? Someone must have run into this before...
Since SWIG doesn't understand boost types, typemaps have to be written. Here's a pair of typemaps for boost::optional<int>
.
From Python, None
or an integer can be passed into a function:
%typemap(in) boost::optional<int> %{
if($input == Py_None)
$1 = boost::optional<int>();
else
$1 = boost::optional<int>(PyLong_AsLong($input));
%}
A returned boost::optional<int>
will be converted to a None or a Python integer:
%typemap(out) boost::optional<int> %{
if($1)
$result = PyLong_FromLong(*$1);
else
{
$result = Py_None;
Py_INCREF(Py_None);
}
%}
A possible C# solution using std::vector
#if SWIGCSHARP
// C++
%typemap(ctype) boost::optional<int32_t> "void *"
%typemap(out) boost::optional<int32_t> %{
std::vector<int32_t> result_vec;
if (!!$1)
{
result_vec = std::vector<int32_t>(1, $1.get());
}
else
{
result_vec = std::vector<int32_t>();
}
$result = new std::vector< uint32_t >((const std::vector< uint32_t > &)result_vec);
%}
// C#
%typemap(imtype) boost::optional<int32_t> "global::System.IntPtr"
%typemap(cstype) boost::optional<int32_t> "int?"
%typemap(csout, excode=SWIGEXCODE) boost::optional<int32_t> {
SWIG_IntVector ret = new SWIG_IntVector($imcall, true);$excode
if (ret.Count > 1) {
throw new System.Exception("Return vector contains more then one element");
}
else if (ret.Count == 1) {
return ret[0];
}
else {
return null;
}
}
#endif //SWIGCSHARP
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With