Re: Typemaps jsoncpp => Python: recursive typemap(outargs)?
William S Fulton <[email protected]> Tue, 9 Mar 2021 23:25:32 +0000
| Newsgroups | gmane.comp.programming.swig |
|---|---|
| Message-ID | <CANGqftDTGLU3F3AVzxrJsC2dqdYoH--KBU-t_j1mhk5TbymmLQ@mail.gmail.com> |
Hi Julien With regards to recursive calls, I suggest your typemap should be a one liner which simply calls into a support function. The support function can then recursively call itself. Have a look at fragments in the Typemaps chapter, where your fragment would contain the support function and the support function would only be generated once no matter how many times the typemap is used. William On Wed, 3 Mar 2021 at 15:02, Julien Marrec <[email protected]> wrote: > Hello, > > First, has anyone wrapped jsoncpp > <https://github.com/open-source-parsers/jsoncpp> in Swig? If I can avoid > reinventing the wheel... > > Otherwise, I basically have a Json::Value toJSON() method in C++. > > I'd like to return a python dict instead (and a Hash in ruby...). So far, > I've done a workaround by creating a std::string toJSONString() { return > toJSON().toStyledString(); }, and using %pythoncode (and %init with > rb_eval_string in ruby). It works (see at end of email if you're > curious), but I'd like to try a typemap(argout) instead. All my attempts > so far have miserably failed, probably because: > > 1. This is pretty much the first time I tried to do a typemap, and, > 2. I have no clue how to do a recursive call to the typemap(argout) > itself. > > Here is one of my attempts (I tried with Json::Value instead of Json::Value > * too) > > #if defined SWIGPYTHON > > %typemap(argout) Json::Value * { > > if ($1->isIntegral()) { > $result = PyLong_FromLongLong($1->asInt64()); > } else if ($1->isNumeric()) { > $result = PyFloat_FromDouble($1->asDouble()); > } else if ($1->isString()) { > $result = PyUnicode_FromString($->.asString()); > } else if ($1->isArray()) { > $result = PyList_New(); > for( const auto& n : *$1) { > // TODO: this should do a recursive call to convert n (which is Json::Value) to a python type... > PyList_Append(n); > } > } else if ($1->isObject()) { > $result = PyDict_New(); > for( const auto& id : $1->getMemberNames()) { > // TODO: this should do a recursive call to convert *$1[id] (which is a Json::Value) to a python type... > PyDict_SetItemString($result, id.c_str(), *$1[id]); > } > } > } > #endif > > The documentation for Json::Value is at > https://open-source-parsers.github.io/jsoncpp-docs/doxygen/class_json_1_1_value.html > > *If someone could nudge me in the right direction, that'd be much > appreciated.* > > Thank you, > > Julien > ------------------------------ > > For reference my current workaround: in epJSON.i: > > #if defined SWIGRUBY > // This isn't super clean and there might be a better way with typemaps in SWIG rather than using a String in between, > // but still helpful I think: we redefine toJSON that will return a native ruby hash. 'json' is part of ruby stdlib since at least ruby 2.5.5 > %init %{ > rb_eval_string("OpenStudio::EPJSON.module_eval { define_method(:toJSON) { |arg| json_str = self.toJSONString(arg); require 'json'; JSON.load(json_str); }; module_function(:toJSON) }"); > %} > #endif > > #if defined SWIGPYTHON > > // Let's use monkey-patching via unbound functions > // Edit: not even needed here > %pythoncode %{ > # Manually added: Lazy-load the json module (python std lib) and return a dict via toJSONString > def toJSON(*args) -> dict: > import json > return json.loads(toJSONString(*args)) > %} > #endif > > > -- > Julien Marrec, EBCP, BPI MFBA > Owner at EffiBEM <http://www.effibem.com> > T: +33 6 95 14 42 13 > > LinkedIn (en <https://www.linkedin.com/in/julienmarrec>) *| *(fr > <https://fr.linkedin.com/in/julienmarrec/fr>) : > <http://www.linkedin.com/in/julienmarrec> > _______________________________________________ > Swig-user mailing list > [email protected] > https://lists.sourceforge.net/lists/listinfo/swig-user > _______________________________________________ Swig-user mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/swig-user