1

I am having a wicked problem with exposing a polymorphic class hierarchy via a factory. I have created an example that demonstrates the problem.

This is all being hosted in a executable with an embedded python(stackless 2.7) interpreter. When I run the executable and get the Python code I can create a variable from the factory (a = MakeB()) this returns a smart pointer to the TestA class but holds an instance of TestB. The problem I have is that when I access the base class member variables/functions it works, but accessing TestB variables/functions generates a segment fault 11 (osx).

The returned instance reports to python that its class is TestB (class reports the same) and the print messages show that TestB was constructed and returned. Of note that it I create TestB directly (opposed to the factory) the base class's variables/functions work correctly.

My actual production code is more complex, but this has boiled it down to this test example. I can provide a backtrace of the segfault if anyone thinks it will help.

Thanks.

>print sys.version
2.7.6a1 Stackless 3.1b3 060516 (default, Jan 10 2014, 13:13:51) 
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.2.79)]

hpp File

class TestA;
typedef boost::shared_ptr<TestA> TestAPtr;
class TestB;
typedef boost::shared_ptr<TestB> TestBPtr;
class TestA
{
public:

    TestA();
    virtual ~TestA();
    static void Boost(void);
    string Aprop;
    void FuncA();

};

class TestB : public TestA
{
public:

    TestB();
    virtual ~TestB();
    static void Boost(void);
    string Bprop;
    void FuncB();
};

cpp File

TestA::TestA() : Aprop("Test A")
{
    printf("Create TestA\n");
}
TestA::~TestA()
{
    printf("Destroy TestA\n");
}
void TestA::Boost(void)
{
    class_< TestA >("TestA", init<>())
        .def("FuncA", &TestA::FuncA)
        .def_readwrite("Aprop", &TestA::Aprop)
        ;
    register_ptr_to_python< boost::shared_ptr<TestA> >();
}
void TestA::FuncA()
{
    printf("Hi From Test A\n");

}

// ------ Test B

TestB::TestB() : TestA(), Bprop("Test B")
{
    printf("Create TestB\n");
}

TestB::~TestB()
{
    printf("Destroy TestB\n");
}
void TestB::Boost(void)
{
    class_< TestB, bases<TestA> >("TestB", init<>())
    .def("FuncB", &TestB::FuncB)
    .def_readwrite("Bprop", &TestB::Bprop)    
    ;
    register_ptr_to_python< boost::shared_ptr<TestB> >();
}
void TestB::FuncB()
{
    printf("Hi From Test B\n");
}

// Factory...
TestAPtr MakeB()
{
    return boost::shared_ptr<TestA>(new TestB());
}

BOOST_PYTHON_MODULE(__builtin__)
{
    TestA::Boost();
    TestB::Boost();

    def("MakeB", MakeB);
}
  • Code works as-is for me. – Barry Sep 25 '15 at 15:04
  • Well that .... Are you using python or stackless python? Did you just build an dll and include it into your python, or did you use a embedded python interpreter in and executable? Trying to figure out what made it work for you? – Robert Babiak Sep 25 '15 at 15:50
  • Works for me as well with all variations of python/stackless, embedded/non-embedded, statically/dynamic linked extension. I had to make some assumptions though. Verify both Boost.Python and the embedding executable are both built against the same version of Python. Also, consider providing a [mcve] (here is an [example](http://coliru.stacked-crooked.com/a/7da9734b0086342f) embedding non-stackless). – Tanner Sansbury Sep 25 '15 at 17:49
  • Will do, thanks for the feedback. – Robert Babiak Sep 25 '15 at 17:57
  • @TannerSansbury Thanks For the example, I think my stackless framework is not correct. I was using GCC, but have tried with clang now. The example that you linked doesn't run with the cmd line that you listed. I think the problem lies in the framework and my python development environment. I think you have given me the pinter at the culprit. Thanks! – Robert Babiak Sep 25 '15 at 18:24
  • I have solved this problem. @TannerSansbury was correct the code worked correctly. My problem came down to using port to install boost python vs using Brew to install. The difference was that Brew installed the lib and the multi threaded libs. I had installed the port version so my multi threaded program was linking against the single threaded libraries. Providing the multi threaded libs solved the problems. – Robert Babiak Oct 07 '15 at 18:36

0 Answers0