Skip to content

Instantly share code, notes, and snippets.

@larsoner
Last active December 21, 2024 18:46
Show Gist options
  • Save larsoner/3c85cd573aa647bb799ff6baefa0a58b to your computer and use it in GitHub Desktop.
Save larsoner/3c85cd573aa647bb799ff6baefa0a58b to your computer and use it in GitHub Desktop.
SWIG -fastdispatch changes arguments that can be used
namespace Example {
typedef enum { DEEP_COPY } DeepCopy;
class MyClass {
public:
MyClass() { }
MyClass(const int N) { }
MyClass(const MyClass& A,const DeepCopy) { }
};
}
%{
#include "example.h"
using namespace Example;
%}
namespace Example {
%naturalvar MyClass;
class MyClass;
}
%{
Example::MyClass* new_Example_MyClass(PyObject* pyobj) {
printf("* MyClass: received a PyObject\n");
Example::MyClass* v;
if (pyobj && PyFloat_Check(pyobj)) {
const double f = PyFloat_AsDouble(pyobj);
const int i = (int)f;
printf("** Received a float %f turned to %d\n", f, i);
v = new Example::MyClass(i);
return v;
}
void* ptr = 0 ;
printf("** Converting to a pointer\n");
if (!SWIG_IsOK(SWIG_ConvertPtr(pyobj,&ptr,SWIGTYPE_p_Example__MyClass,SWIG_POINTER_EXCEPTION))) {
printf("** FAILED\n");
return NULL;
}
printf("** Returning a reinterpret_cast MyClass\n");
v = new Example::MyClass(*(reinterpret_cast<Example::MyClass*>(ptr)),Example::DEEP_COPY);
printf("** Done\n");
return v;
}
%}
namespace Example {
%typecheck(SWIG_TYPECHECK_POINTER) MyClass& {
if (PyFloat_Check($input))
$1 = 1;
else if (SWIG_IsOK(SWIG_ConvertPtr($input, 0, 0, 0)))
$1 = 1;
else
$1 = 0;
}
%typemap(in) MyClass& {
$1 = new_Example_MyClass($input);
}
%typemap(freearg) MyClass& {
if ($1) delete $1;
}
}
%extend Example::MyClass {
MyClass(PyObject* pyobj) { return new_Example_MyClass(pyobj); }
}
%include "example.h"
.PHONY: all clean openmeeg_wrap.cxx _example.so test1 test2 test3 test4 test5
all : clean example_wrap.cxx _example.so test1 test2 test3 test4 test5
clean:
rm -f *.o
rm -f *.so
rm -f *wrap*.c*
rm -f *wrapper.py
rm -Rf build
rm -Rf __pycache__
example_wrap.cxx:
@echo
swig -c++ -v -module example -interface _example -fastdispatch -python example.i
_example.so:
@echo
python setup.py build_ext --inplace
test1: # Always okay
@echo
python -c "from example import MyClass, DEEP_COPY; print(f'{MyClass()}')"
test2: # Always okay
@echo
python -c "from example import MyClass, DEEP_COPY; print(f'{MyClass(MyClass(), DEEP_COPY)}');"
test3: # Always okay
@echo
python -c "from example import MyClass, DEEP_COPY; print(f'{MyClass(1)}');"
test4: # Always okay
@echo
python -c "from example import MyClass, DEEP_COPY; print(f'{MyClass(1.)}')"
test5: # fails without -fastdispatch
@echo
python -c "from example import MyClass, DEEP_COPY; print(f'{MyClass(1., DEEP_COPY)}')"
from setuptools import setup, Extension
setup(
name = 'example',
version = '0.1',
ext_modules = [Extension('_example', sources=['example_wrap.cxx'])],
py_modules = ["example"],
)
@larsoner
Copy link
Author

Running make with -fastdispatch as above on line 14, all tests pass including test5:

python -c "from example import MyClass, DEEP_COPY; print(f'{MyClass(1., DEEP_COPY)}')"
* MyClass: received a PyObject
** Received a float 1.000000 turned to 1
<example.MyClass; proxy of <Swig Object of type 'Example::MyClass *' at 0x76dd7ffd05a0> >

Removing -fastdispatch it fails:

python -c "from example import MyClass, DEEP_COPY; print(f'{MyClass(1., DEEP_COPY)}')"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/larsoner/python/gists/swig2/example.py", line 67, in __init__
    _example.MyClass_swiginit(self, _example.new_MyClass(*args))
                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: Wrong number or type of arguments for overloaded function 'new_MyClass'.
  Possible C/C++ prototypes are:
    Example::MyClass::MyClass()
    Example::MyClass::MyClass(int const)
    Example::MyClass::MyClass(Example::MyClass const &,Example::DeepCopy const)
    Example::MyClass::MyClass(PyObject *)

make: *** [Makefile:39: test5] Error 1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment