|
View:
New views
5 Messages
—
Rating Filter:
Alert me
|
|
|
Accepting None as a valid input for the constructor of a C++ class.Dear swig users,
I have a C++ class that is wrapped into a Python shadow class. In addition to regular Python input (say, a number), I would like to allow users to pass None from the user interface and tells the C++ class no invalid input is given. It is more or less like using -1 as a default parameter when only positive numbers are allowed. However, SWIG does not seem to allow such usage because it will not pass None to the C++ class even if it accepts such an input (e.g. with a constructor that accepts a PyObject * object). Whenever I pass None, I would get an error message such as "Invalid null reference". When I read the wrapper file, I find the following piece of code: if (obj5) { res6 = SWIG_ConvertPtr(obj5, &argp6, SWIGTYPE_p_simuPOP__uintList, 0 | SWIG_POINTER_IMPLICIT_CONV); if (!SWIG_IsOK(res6)) { SWIG_exception_fail(SWIG_ArgError(res6), "in method '" "new_stat" "', argument " "6"" of type '" "simuPOP::uintList const &""'"); } if (!argp6) { SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_stat" "', argument " "6"" of type '" "simuPOP::uintList const &""'"); } arg6 = reinterpret_cast< simuPOP::uintList * >(argp6); } The problem is that when SWIG_ConvertPtr is called SWIGRUNTIME int SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int flags, int *own) { if (!obj) return SWIG_ERROR; if (obj == Py_None) { if (ptr) *ptr = 0; return SWIG_OK; } else { It treats Py_None directly as a special case and does not call the implicit constructor at all. Is there a way to get around this problem?? I guess what I need is that SWIG passes Py_None to the constructor when flag SWIG_POINTER_IMPLICIT_CONV is set to true. Many thanks in advance. Bo ------------------------------------------------------------------------------ _______________________________________________ Swig-user mailing list Swig-user@... https://lists.sourceforge.net/lists/listinfo/swig-user |
|
|
Re: Accepting None as a valid input for the constructor of a C++ class.On Sun, 5 Jul 2009, Bo Peng wrote: > I have a C++ class that is wrapped into a Python shadow class. In > addition to regular Python input (say, a number), I would like to > allow users to pass None from the user interface and tells the C++ > class no invalid input is given. It is more or less like using -1 as a > default parameter when only positive numbers are allowed. > > However, SWIG does not seem to allow such usage because it will not > pass None to the C++ class even if it accepts such an input (e.g. with > a constructor that accepts a PyObject * object). Whenever I pass None, > I would get an error message such as "Invalid null reference". My understanding/recollection is that None is acceptable for any pointer type (and is converted to a null pointer), but is not acceptable for a reference (which makes sense). I'm not clear on the details of what you're doing, but that would appear to be the cause of that error message. This behavior is dictated by the standard typemaps for pointers and references. Josh ------------------------------------------------------------------------------ _______________________________________________ Swig-user mailing list Swig-user@... https://lists.sourceforge.net/lists/listinfo/swig-user |
|
|
Re: Accepting None as a valid input for the constructor of a C++ class.Josh Cherry wrote:
> > On Sun, 5 Jul 2009, Bo Peng wrote: > >> I have a C++ class that is wrapped into a Python shadow class. In >> addition to regular Python input (say, a number), I would like to >> allow users to pass None from the user interface and tells the C++ >> class no invalid input is given. It is more or less like using -1 as a >> default parameter when only positive numbers are allowed. >> >> However, SWIG does not seem to allow such usage because it will not >> pass None to the C++ class even if it accepts such an input (e.g. with >> a constructor that accepts a PyObject * object). Whenever I pass None, >> I would get an error message such as "Invalid null reference". > > My understanding/recollection is that None is acceptable for any pointer > type (and is converted to a null pointer), but is not acceptable for a > reference (which makes sense). I'm not clear on the details of what > you're doing, but that would appear to be the cause of that error message. > This behavior is dictated by the standard typemaps for pointers and > references. > !argp) are in swigtype.swg and the preprocessed versions are shown below: %typemap(in, noblock=1) SWIGTYPE *(void *argp = 0, int res = 0) { res = SWIG_ConvertPtr($input, &argp,$descriptor, $disown | 0 ); if (!SWIG_IsOK(res)) { SWIG_exception_fail(SWIG_ArgError(res), "in method '" "$symname" "', argument " "$argnum"" of type '" "$type""'"); } $1 = reinterpret_cast< $ltype >(argp); } %typemap(in, noblock=1) SWIGTYPE & (void *argp = 0, int res = 0) { res = SWIG_ConvertPtr($input, &argp, $descriptor, 0 ); if (!SWIG_IsOK(res)) { SWIG_exception_fail(SWIG_ArgError(res), "in method '" "$symname" "', argument " "$argnum"" of type '" "$type""'"); } if (!argp) { SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "$symname" "', argument " "$argnum"" of type '" "$type""'"); } $1 = reinterpret_cast< $ltype >(argp); } William ------------------------------------------------------------------------------ Enter the BlackBerry Developer Challenge This is your chance to win up to $100,000 in prizes! For a limited time, vendors submitting new applications to BlackBerry App World(TM) will have the opportunity to enter the BlackBerry Developer Challenge. See full prize details at: http://p.sf.net/sfu/blackberry _______________________________________________ Swig-user mailing list Swig-user@... https://lists.sourceforge.net/lists/listinfo/swig-user |
|
|
Re: Accepting None as a valid input for the constructor of a C++ class.> Indeed and the typemaps showing the difference with the extra check (for
> !argp) are in swigtype.swg and the preprocessed versions are shown below: But do you agree that None/Null should be passed to the constructor of a class for which implicitconv is defined? Please refer to my previous email for an example. Thanks. Bo ------------------------------------------------------------------------------ Enter the BlackBerry Developer Challenge This is your chance to win up to $100,000 in prizes! For a limited time, vendors submitting new applications to BlackBerry App World(TM) will have the opportunity to enter the BlackBerry Developer Challenge. See full prize details at: http://p.sf.net/sfu/blackberry _______________________________________________ Swig-user mailing list Swig-user@... https://lists.sourceforge.net/lists/listinfo/swig-user |
|
|
Re: Accepting None as a valid input for the constructor of a C++ class.> But do you agree that None/Null should be passed to the constructor of
> a class for which implicitconv is defined? Please refer to my previous > email for an example. I just realized that 'my previous email' was sent only to Josh so I am resending it to the list: Thank you very much for your reply. You are right that SWIG treats None as NULL pointer so it can only be used for pointer types. In this case, either NULL (None) or the pointer of a real object is passed from Python to C++. My problem might be solved by switching from a reference type to a pointer type and check for None from where my uintList object is received, not from uintList itself. However, I do think there is a bug here. If a type is set to be converted implicitly (%implicitconv), its constructor might accept a pointer as its input type and a NULL pointer should be allowed. Using a silly example ================== test.h ======== class Foo { public: Foo(int * i) : num(i == NULL ? 0 : 1) {} private: int num; }; void func(Foo f) { } ============= test.i ================= %module test %{ #include "test.h" %} %implicitconv Foo; %include "test.h" =============== command ============= % swig -c++ -python -shadow test.i % g++ test_wrap.cxx -shared -o _test.so -fPIC -I/usr/include/python2.4 I get a module test with type Foo that cannot be implicitly converted: >>> from test import * >>> func(Foo(None)) >>> func(None) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: invalid null reference in method 'func', argument 1 of type 'Foo' For the last command, I would expect that None is passed to Foo(int *). Cheers, Bo ------------------------------------------------------------------------------ Enter the BlackBerry Developer Challenge This is your chance to win up to $100,000 in prizes! For a limited time, vendors submitting new applications to BlackBerry App World(TM) will have the opportunity to enter the BlackBerry Developer Challenge. See full prize details at: http://p.sf.net/sfu/Challenge _______________________________________________ Swig-user mailing list Swig-user@... https://lists.sourceforge.net/lists/listinfo/swig-user |
| Free embeddable forum powered by Nabble | Forum Help |