Reputation: 5875
Here's a very simple C function:
bool GetSomething(string* result)
After calling this function, the return value should indicate if the result
holds the needed information, and user can check the return value to handle accordingly.
To SWIG this function to be used in Python code, I use the default typemaps.i
file and then changed the function to
bool GetSomething(string* OUTPUT)
This works but still cumbersome. I'll have to do this to get the result I want:
success, result = GetSomething()
if success:
# handle result
else:
# throw exception
Ideally I'd like to have this interface instead:
result = GetSomething()
if result:
# handle result
Any help would be appreciated.
Upvotes: 2
Views: 1747
Reputation: 177901
Here's an example .i file of the idea mentioned in comments. Convert a successful return status to None
and a failing return status to an exception in Python, and append output parameters to the return value. This requires no changes to the C++ code base:
%module x
%include <exception.i>
// convert non-zero int return values to exceptions
%typemap(out) int %{
if($1)
SWIG_exception(SWIG_RuntimeError,"non-zero return value");
$result = Py_None;
Py_INCREF(Py_None); // Py_None is a singleton so increment its reference if used.
%}
// Easy way for int*, but customize below for more complicated types
// %apply int* OUTPUT {int*};
// suppress the output parameter as an input.
%typemap(in,numinputs=0) int* (int tmp) %{
$1 = &tmp;
%}
// append int* output parameters to the return value.
%typemap(argout) int* {
PyObject* tmp = PyLong_FromLong(*$1);
$result = SWIG_Python_AppendOutput($result,tmp);
}
// %inline declares and exposes a function
%inline %{
int func(int val, int* pOut)
{
if(val < 1)
return 1;
*pOut = 2 * val;
return 0;
}
%}
If you SWIG this .i with swig -python -c++ x.i
and compile the result into a Python extension:
>>> import x
>>> x.func(2)
4
>>> x.func(0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: non-zero return value
Upvotes: 5
Reputation: 5875
My current hack, hope this helps someone.
%{
#define GetSomething 1
%}
%typemap(out) bool %{
#if $symname == 1
if (result) {
return Py_FromString(arg0->data());
} else {
return Py_None;
}
#endif
%}
Upvotes: 0