Thanks again Bob, for posterity here is what I can up with:


%typemap(in) const path& {



      // check if input is a path already

      void *vptr = 0;

     int res = SWIG_ConvertPtr($input, &vptr, SWIGTYPE_p_openstudio__path, 0);

      if (SWIG_IsOK(res)) {

        if (vptr) {

          // make a new copy, freearg typemap will call delete on this below

          openstudio::path * p = reinterpret_cast< openstudio::path * >(vptr);

          $1 = (openstudio::path *)new openstudio::path(*(openstudio::path const *)p);       


          SWIG_exception_fail(SWIG_ValueError, Ruby_Format_TypeError("invalid null reference ", "openstudio::path const &", "$symname", 1, $input));


      } else if (TYPE($input) == T_STRING) {

        // otherwise, if a string

        Check_Type($input, T_STRING);

        std::string s(STR2CSTR($input));

        $1 = new openstudio::path(openstudio::toPath(s));

      } else {

        SWIG_exception_fail(SWIG_ArgError(res), Ruby_Format_TypeError( "", "openstudio::path const &", "$symname", 1, $input));




    %typemap(freearg) const path& {

      if ($1){

        delete $1;




It seems to work for now,


From: Bob Hood []
Sent: Saturday, December 14, 2013 10:59 AM
To: Macumber, Daniel;
Subject: Re: [Swig-user] Implicit conversion in Ruby?


On 12/14/2013 9:06 AM, Macumber, Daniel wrote:

Thanks for looking into this Bob!  I think you are right that I want to do an explicit conversion, but I am not understanding how to do that with typemaps.  The problem I am having is that in ruby the input type is String.  SWIG has a map somewhere that converts String to std::string, I want to add one that converts String to path.  I’ve tried looking in the files related to strings in \SWIG\Lib\ruby\ but I am not seeing anything that makes sense to me.


  1) Error:


TypeError: Expected argument 0 of type openstudio::path const &, but got String


        in SWIG method 'funcOnlyTakesAPath'

    Path_Test.rb:48:in `funcOnlyTakesAPath'

    Path_Test.rb:48:in `test_funcOnlyTakesAPath'

I can't couch this in terms of Ruby, because I've never wrapped that language.  I have done Python extensively, so here is a SWIG typemap that performs the conversion you're after.

I've defined a simple class:

    class path
        path(const std::string& str) {}

and a function prototype:

    void funcOnlyTakesAPath(const path& p);

in the same header for SWIG to process.

In my SWIG interface file, I have the following typemap that converts a Python None or string into a path class instance:

    %typemap(in) const path& {
        $1 = NULL;
        if($input == Py_None)
            $1 = new path("");
        else if(PyString_Check($input))
            $1 = new path(PyString_AsString($input));

    %typemap(freearg) const path& {
        if($1) delete $1;

In Python, invoking this as:


functions as you want, with an instance of the path class being constructed and passed to the internal C++ funcOnlyTakesAPath() function as a 'const path&' type.  You just need to replace the Python API idioms for Ruby in this code to detect and convert the types.