简体   繁体   中英

Exporting templated member function of a templated class in MSVC C++ DLL

I am compiling PCL library ( https://github.com/PointCloudLibrary/pcl.git ) into DLLs to be used in my own project. It's a project which makes heavy use of C++ templates. In order to decrease compile time, I am using PCL_NO_PRECOMPILE set to OFF , which means that the implementation is not in the header files. My application can only use the classes and functions which have been instantiated while compiling PCL.

The problem is that templated member functions of a templated class are not being exported in the MSVC DLL. I am using MS Visual Studio 2017 community edition. Here's the specific problem.

I am creating a child class of pcl::Hough3DGrouping , which is defined at https://github.com/PointCloudLibrary/pcl/blob/master/recognition/include/pcl/recognition/cg/hough_3d.h . The specific function of interest is the protected function computeRf() defined at the bottom of the file on line 510. When I look at the exported symbols in the DLL, I do not see computeRf() . Hence I am not able to use it from my custom code.

I assumed that computeRf() is not being exported in the DLL because it's templated. Hence, I tried explicit instantiation in https://github.com/PointCloudLibrary/pcl/blob/master/recognition/src/cg/hough_3d.cpp . Specifically I added

template void pcl::Hough3DGrouping<pcl::PointXYZRGB, pcl::PointXYZRGB, pcl::ReferenceFrame, pcl::ReferenceFrame>::computeRf<pcl::PointXYZRGB, pcl::ReferenceFrame>(const boost::shared_ptr<const pcl::PointCloud<pcl::PointXYZRGB> >, pcl::PointCloud<pcl::ReferenceFrame>)

on line 44 of https://github.com/PointCloudLibrary/pcl/blob/master/recognition/src/cg/hough_3d.cpp .

When I compile, I get the error:

E:\libs\pcl\src\recognition\src\cg\hough_3d.cpp(45): error C3190: 'void pcl::Hough3DGrouping<pcl::PointXYZRGB,pcl::PointXYZRGB,pcl::ReferenceFrame,pcl::ReferenceFrame>::computeRf(const boost::shared_ptr<const pcl::PointCloud<PointT>>,pcl::PointCloud<PointModelRfT>)' with the provided template arguments is not the explicit instantiation of any member function of 'pcl::Hough3DGrouping<pcl::PointXYZRGB,pcl::PointXYZRGB,pcl::ReferenceFrame,pcl::ReferenceFrame>'
    with
    [
        PointT=pcl::PointXYZRGB,
        PointModelRfT=pcl::ReferenceFrame
    ]

My goal is to create a child class of pcl::Hough3DGrouping in my application and call the method computeRf() of the base class from it. The only instantiations I need are:

pcl::Hough3DGrouping<pcl::PointXYZRGB, pcl::PointXYZRGB, pcl::ReferenceFrame, pcl::ReferenceFrame>
pcl::Hough3DGrouping<pcl::PointXYZRGB, pcl::PointXYZRGB, pcl::ReferenceFrame, pcl::ReferenceFrame>::computeRf<pcl::PointXYZRGB, pcl::ReferenceFrame>

How should I go about doing this with minimal changes to PCL source code?

Templates cannot be exported from DLLs, obviously.

Copy pasting what you tried to export and the signature:

template<typename PointType, typename PointRfType> void
computeRf
(const boost::shared_ptr<const pcl::PointCloud<PointType> > &input, pcl::PointCloud<PointRfType> &rf)

template void
pcl::Hough3DGrouping<pcl::PointXYZRGB, pcl::PointXYZRGB, pcl::ReferenceFrame, pcl::ReferenceFrame>::
computeRf<pcl::PointXYZRGB, pcl::ReferenceFrame>
(const boost::shared_ptr<const pcl::PointCloud<pcl::PointXYZRGB> >, pcl::PointCloud<pcl::ReferenceFrame>)

I notice a difference. You tried to export something whose function arguments are not references. The template method of the template class has reference function arguments.

The compiler said "these don't match". I'll believe it.

Make the arguments references and it will match a method in the class.

template void
pcl::Hough3DGrouping<pcl::PointXYZRGB, pcl::PointXYZRGB, pcl::ReferenceFrame, pcl::ReferenceFrame>::
computeRf<pcl::PointXYZRGB, pcl::ReferenceFrame>
(const boost::shared_ptr<const pcl::PointCloud<pcl::PointXYZRGB> >&, pcl::PointCloud<pcl::ReferenceFrame>&)

You have two errors in the instantiatrion line:

  1. Hough3DGrouping template argument order is wrong, should be

     pcl::PointXYZRGB, pcl::ReferenceFrame, pcl::PointXYZRGB, pcl::ReferenceFrame 

    and not

     pcl::PointXYZRGB, pcl::PointXYZRGB, pcl::ReferenceFrame, pcl::ReferenceFrame 
  2. You forgot & s in the parameter list:

     computeRf(const boost::shared_ptr<const pcl::PointCloud<pcl::PointXYZRGB>>&, pcl::PointCloud<pcl::ReferenceFrame>&) 

    Template arguments of computeRf are not needed because deduction works.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM