Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unresolved external symbols since Visual Studio 2015 update 3: boost python linking error if destructor is virtual

We are getting strange unresolved symbols linking errors since we updated to Visual Studio 2015 update 3. Anyone else encountered the same kind of issues ?

What is really weird is that boost::get_pointer is a template method, defined in a boost header. I do not understand how we can get an undefined external symbol in that case :(.

Here is a reproducer, with boost 1.61 and Python 3.5.1:

#include <vector>
#include <boost/python.hpp>

using namespace boost::python;

class Canard {
public:
    Canard() {}
    virtual ~Canard() {}
};

BOOST_PYTHON_MODULE(coin)
{
     register_ptr_to_python< std::shared_ptr<Canard> >();
}

And the error:

 Severity   Code    Description Project File    Line
Error   LNK2019 unresolved external symbol "class Canard const volatile * __cdecl boost::get_pointer<class Canard const volatile >(class Canard const volatile *)" (??$get_pointer@$$CDVCanard@@@boost@@YAPEDVCanard@@PEDV1@@Z) referenced in function "private: static struct _typeobject * __cdecl boost::python::objects::make_ptr_instance<class Canard,struct boost::python::objects::pointer_holder<class std::shared_ptr<class Canard>,class Canard> >::get_derived_class_object<class Canard>(struct boost::mpl::bool_<1>,class Canard const volatile *)" (??$get_derived_class_object@VCanard@@@?$make_ptr_instance@VCanard@@U?$pointer_holder@V?$shared_ptr@VCanard@@@std@@VCanard@@@objects@python@boost@@@objects@python@boost@@CAPEAU_typeobject@@U?$bool_@$00@mpl@3@PEDVCanard@@@Z)   CCMasterKernelPyPy  C:\work\dev\builds\internal\Master\SDK\MasterKernelPyPy\main.obj    1

But as soon as I remove the virtual in front of the destructor of the Canard class, then it starts working.... Does anyone have a clue ? Is it a Visual Studio bug ?

like image 577
CanardMoussant Avatar asked Jul 08 '16 07:07

CanardMoussant


1 Answers

Visual Studio 2015 update 3 has added lots of features and improvements (see the release notes https://www.visualstudio.com/news/releasenotes/vs2015-update3-vs#visualcpp). It also have some known issues (https://msdn.microsoft.com/vs-knownissues/vs2015-update3 see the Passing non-pointer-like types to uninitialized_copy section).

To fix your problem you need to explicitly specify the conversion to pointer of your class, explicitly:

namespace boost
{
    template <>
    Canard const volatile * get_pointer<class Canard const volatile >(
      class Canard const volatile *c)
    {
        return c;
    }
}

Good luck, Ohad

like image 138
Ohad Oded Avatar answered Nov 20 '22 13:11

Ohad Oded