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:

test_funcOnlyTakesAPath(Path_Test):

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

"./here"

        in SWIG method 'funcOnlyTakesAPath'

    Path_Test.rb:48:in `funcOnlyTakesAPath'

    Path_Test.rb:48:in `test_funcOnlyTakesAPath'

 

Thanks again,
Dan

 

From: Bob Hood [mailto:bhood2@comcast.net]
Sent: Saturday, December 14, 2013 6:31 AM
To: Macumber, Daniel; swig-user@lists.sourceforge.net
Subject: Re: [Swig-user] Implicit conversion in Ruby?

 

On 12/13/2013 10:49 PM, Macumber, Daniel wrote:

Hello, I have a question that I am sure has an easy answer, but I don’t know what it is.  I have a class in C++ called path, this class does not have a constructor from std::string in C++.  The class is not in a library I can modify.  I have extended the class in Ruby to have a constructor from std::string:

 

%extend path{

  // constructor from std::string

  path(const std::string& s){

    path *p;

    p = new path(toPath(s));

    return p;

  }

};

 

I also created a function that takes a const reference to a path:

 

void funcOnlyTakesAPath(const path& p);

 

I can call this function like:

 

p = Path.new("./here")

funcOnlyTakesAPath(p)

 

However, I cannot call this function like:

 

funcOnlyTakesAPath("./here")

 

How can I get SWIG to allow implicit conversion of std::string to path?


What you're trying to do above doesn't even work from C++.  Your function doesn't take an instance of std::string (which provides an implicit conversion from "const char *").  I wrote a small test module (called test3.cpp):

    #include <string>

    class path
    {
    public:
        path(const std::string& s) {}
    };

    void funcOnlyTakesAPath(const path& p) {}

    int main(void)
    {
        funcOnlyTakesAPath("./here");
    }


and it produces this error when compiled:

    test3.cpp(13) : error C2664: 'funcOnlyTakesAPath' : cannot convert parameter 1 from 'const char [7]' to 'const path &'
            Reason: cannot convert from 'const char [7]' to 'const path'
            No constructor could take the source type, or constructor overload resolution was ambiguous


If you explicitly create a path instance, like this:

    funcOnlyTakesAPath( path("./here") );

Then it works.  So, it's probably unreasonable to expect SWIG to perform this kind of implicit conversion.  You will probably need to do an explicit conversion (perhaps a typemap?).