Neerav Mehta
Neerav Mehta

Reputation: 143

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?

Upvotes: 0

Views: 633

Answers (2)

n. m. could be an AI
n. m. could be an AI

Reputation: 119877

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.

Upvotes: 0

Yakk - Adam Nevraumont
Yakk - Adam Nevraumont

Reputation: 275405

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>&)

Upvotes: 1

Related Questions