[Python] Swig: C++ / Python director and std::vector<double>

Discussão em 'Python' iniciado por Stack, Novembro 29, 2024.

  1. Stack

    Stack Membro Participativo

    I try to wrap a c++ code in python with swig. I use the director instruction to overload few methods of a virtual class but I have some issues with the methods that should return tabulated data: std::vector or Eigen::Vector.

    Let's say we have a c++ class

    class myCppClass
    {
    public:
    myCppClass(){}
    virtual std::vector<double> compute_things();
    };


    The .i file that wrap this class looks like:

    %module(package="example", directors="1", allprotected="1", "threads"=1) My_Example

    %{
    #include <MyCppClass.h>
    }

    %import <typemaps.i>
    %include <std_vector.i>
    %include <eigen.i>
    %import "numpy.i"

    %feature("director") myCppClass;

    %include <MyCppClass.h>


    Then in python

    class myPythonClass(myCppClass):

    def __init__(self):
    super().__init__()

    def compute_things(self):
    return np.array([2.0, 1.0])


    myclass = myPythonClass()
    myclass.compute_things()



    Once everything is compiled, the class creation goes well but the compute_things() method crash without any clue about the error. If I return an int or a double everything goes well. I put few error handling instruction in the .i file but none them are activated.

    %feature("director:except") {
    if ($error != NULL) {
    PyErr_Print();
    if (PyErr_GivenExceptionMatches($error, PyExc_TypeError)) {
    throw std::invalid_argument("director:except TypeError");
    }
    else {
    throw Swig::DirectorMethodException("Unknown exception thrown by Python SWIG director method");
    }
    }
    }

    %exception{
    try { $action }
    catch (std::invalid_argument& exc) {
    if (std::string(exc.what()) == "director:except TypeError") {
    SWIG_exception_fail(SWIG_TypeError, "TypeError exception thrown by Python SWIG director method");
    }
    else {
    std::string message = std::string("Exception '") + std::string(exc.what()) + "' thrown by C++ function : $fulldecl";
    SWIG_exception_fail(SWIG_ValueError, message.c_str());
    }
    }
    catch (Swig::DirectorMethodException& exc) {
    SWIG_exception_fail(SWIG_UnknownError, exc.what());
    }
    catch (Swig::DirectorException &e) { SWIG_fail; }
    catch (...) {
    SWIG_exception_fail(SWIG_UnknownError, "Unknown exception thrown by C++ function : $fulldecl");
    }
    }

    %include "exception.i"
    %exception
    {
    try
    {
    $action
    }
    catch (const std::runtime_error& e) {
    SWIG_exception(SWIG_RuntimeError, e.what());
    }
    catch (const std::invalid_argument& e) {
    SWIG_exception(SWIG_ValueError, e.what());
    }
    catch (const std::eek:ut_of_range& e) {
    SWIG_exception(SWIG_IndexError, e.what());
    }
    catch (...) {
    SWIG_exception(SWIG_RuntimeError, "unknown exception");
    }
    }


    Does I reached a limitation of Swig or there is something I am missing ?

    Thanks a lot for your help.

    Continue reading...

Compartilhe esta Página