Archived

This forum has been archived. Please start a new discussion on GitHub.

Swig?

http://www.swig.org

Dunno if y'all have come across this before? It may make creating bindings for other languages a bit faster in the short term. I've used it for Python, Java, and Perl and it works quite well.

May also be worth considering from the point of view that if someone has an API or class library that they would like to expose using ICE, swig might be able to generate the .ice definitions, and maybe even some of the implementation.

bye
John

Comments

  • No, I haven't seen this before. I just had a look, and it certanly looks interesting. Thanks for that!

    Cheers,

    Michi.
  • I had a look a Swig a few years ago. Yeah, it would be great to specify the mapping between a C++ library and all the popular scripting language *once*, however I was disappointed overall. YMMV, of course.
    • It's based philosophically and in various specific details on the Perl "XS" binding technology. As you probably know if you've done much scripting language work, Perl has the *worst* C API of all the popular scripting languages. Python, by contrast, has an *excellent* C API. By using Swig you are going back to using Perl/XS style technology, and that's quite painful it you're used to something much better.

    • It just doesn't handle C++ very well at all. I could barely get it to call a virtual function properly with a *lot* of work. As for templates, the standard template library and the string class - forget it. At the time, it just couldn't handle these at all.
    • I found it was a lot more work than claimed in the documentation. I had to write a lot of the "mapping specification" for different types by hand. It only automatically generated the integration code for fairly simple cases.

    I admit this was 3 years ago, and looking the documentation now they claim to have better C++ support ... but I'll believe it when I see it. It's a difficult problem, as the Perl/XS/Swig style of integration *requires* that the tool understand the language being interfaced to, as the tool parses specially marked up versions of the header files. For C, that's feasible. For C++, that's quite a challenge, and very error prone. They've basically got to write most of a C++ compiler if they want to get it right in all cases!

    So, I might take another look as it's been a while. Perhaps the C++ support is better ... but even then it' going to be hard to overcome the "lowest common denominator" nature of it. Once you've used the Python C API (for example), parsing specially marked up header files and writing up "type mapping" fragments just seems incredibly backwards.

    Anyway, those were my conclusions at the time, and these are the things I'd definitely be looking at with a critical eye were I to re-evaluate Swig.
  • I've had another look at Swig. I was kind of waiting for a reply from the OP to see what he thought about my points, but since there clearly isn't going to be one I'll go ahead and talk about what I found anyway.

    I tried a simple "StringStack" class that accepts std::string objects and keeps them in a std::vector<std::string> member variable. It also has an overloaded "push" method that accepts a std::vector<std::string> as an argument and pushes the entire vector onto the stack. There's also a "get_contents" method that returns a std::vector<std::string>. Then I wrote up a Swig definition of this interface, ran it through Swig and built the resulting source and my class implementation into a shared library.

    Then I tried to use the resulting module from Python. This didn't worked perfectly at first. It did "import" correctly, and I could create an instance of StringStack. However, there is no "automatic" mapping between Python strings and std::string, so it was treating std::string as an opaque pointer (since I didn't talk about it in the Swig definition file). However, some digging through the docs revealed that there is a "type mapping" for std::string distributed with Swig. After including this in the Swig definition file, it worked absolutely perfectly. There's also a type mapping included for std::vector, so after including that in the definition I am also able to pass and return std::vectors as if they were the built-in Python list type. So that's pretty cool, and a vast improvement. All the method calls work fine, and appear from the Python side to just be method calls on an ordinary object, which is also a massive improvement - you had to call functions before that took the objects as the first argument IIRC. The overloaded "push" worked perfectly, too.

    That said, typemaps *only* exist for std::string and std::vector so far. So it you want more STL types than that in your script/C++ interface, you'll have to wait or do it yourself. Note that the class may *use* other types internally, that doesn't matter. It's only when you want to manipulate the objects in the scripting language itself you'll need a typemap.

    Then I tried to write a Perl program that performed the same actions as the Python code. This proved more problematic, as the std::vector type map didn't appear to be working. However, after asking on the Swig mailing list it was revealed that this is fixed in the next release candidate. So after an upgrade it worked beautifully. It's obvious, however, that this is very new.

    Things I didn't try - inheritance and my own template classes. However, this is a huge leap forward just as it is. I'm going to start using it, I think. Or at least keep mucking about with it. It *still* uses specification files, which have the quite odd Perl/XS syntax, and I imagine they may become a bit of a maintenance problem keeping them in sync with the real class declarations. It would clearly be better if they just interpreted the actual header files, but this is obviously very difficult.

    On the whole though, my negative impressions are almost entirely reversed. The mailing list is also very responsive and from being on it for a few days it's safe to say that the team is dedicated to providing decent C++ support.
  • Thanks for your comments Derek, that's certainly useful!

    Cheers,

    Michi.
  • I couldn't let my original criticism stand, given the huge improvement in C++ support!

    I'd now be cautiously optimistic about using Swig on the ICE C++ classes.
  • Check out SWIG Again!

    Hi folks,

    I encourage you to have another peek at SWIG. There have been many improvements in the last several years, especially with respect to C++.

    I have had good experiences with it, it's a neat tool.

    _Jesse Williamson ;-};
  • Ruby on ICE

    Googling for "swig ruby" leads to the recent article http://www.ociweb.com/jnb/jnbJan2006.html, containing concise but complete examples of how to use SWIG for merging a C++ class into Java and Ruby.

    For me, the Ruby section is of particular interest, because I'd really like to use Ruby as the language-of-choice for writing ICE clients. The "Person" example compiled and ran out-of-the-box, so my hopes are good that the rest can be done just as easily.

    (1) I rewrote the "printer" examples in C++, Java, and Python with the Ice::Application framework in order to use local "config" files (and to have more compact code).

    (2) It seems only natural to try to do something similar in Ruby (at least on the client-side).

    (3) Lacking a Ruby language mapping, I tried to apply SWIG. See attachment.

    I've succeeded in merging Ice::Application in a preliminary Ruby script! Activating cross-language polymorphism, converting Ruby ARRAYs into "char**", and overwriting Ice::Application::run() work already. The Ruby PrinterClient even requires and reads the local "config" file!

    Now I'm stuck with the Ice::Communicator interface; SWIG/Ruby do not resolve the pointee type returned from Ice::Application::communicator() correctly, so "stringToProxy()" is not available in the list of member functions.

    The attached archive contains the C++/SWIG/Ruby code I hacked together, plus a Makefile to compile the required stuff from scratch. This works on OpenSUSE Linux with g++ 4.0.2, swig 1.3.24, and Ice 3.0.1.
  • I'm totally agree with Jesse and Andreas, i've already use swig for complex C++ programs to manipulate C++ class in ruby and Python and it works very well. It is why you should take a look at this very nice software.

    Of course congratulation for the new Ice release. !

    Joel
  • I hadn't had any time to dig into the "Ruby on ICE" idea, so no news to report in this respect.

    However, having done some more work on the Ruby side, I recently played with the QtRuby binding. It seems that the QtRuby interface for Qt3/C++ was created with the help of the SMOKE wrapper generator (just as Korundum is a Ruby wrapper for the KDE llibraries). I have no idea how intimate SMOKE is connected to Qt/KDE "only", or if it could be used as a general-purpose wrapper generator for C++ libraries like Ice/C++, but from what I've seen in QtRuby, the library binding is extremely "natural" to use in Ruby.

    Does anyone in this forum have more knowledge of this approach?
  • marc
    marc Florida
    We are currently working on Ice for Ruby. This will be a client-side only mapping, just like Ice for PHP. We do not use SWIG or any other tool, but simply the Ruby C interface.
  • Marc,

    That's excellent news! I'm looking forward to the results.
  • Treat COM as a language mapping

    I think bindings to and from as many languages as possible are essential.

    SWIG and COM

    Swig now has support for COM as a "language". Could not ICE have support for CORBA and COM in some similar way? I have the benefit of using ICE on two new projects, but I imagine ICE could also be useful on older codebases using COM or CORBA.