Predator's Vision

画像処理、3D点群処理、DeepLearning等の備忘録

PCL1.7.2で一部のライブラリがエラーLNK1189でビルドできない問題の対処

PCLのビルド中にpcl_featureについては下記のようなエラーメッセージが出て使えなくなってしまった。

fatal error LNK1189: オブジェクトまたはメンバーの数がライブラリの最大許容数 65535 を超えています。


調べたところ下記のページが見つかった。被害者の共通点は Visual Studio を使っていること。

Visual Studioコンパイラはライブラリ内のメンバー数に制限を課しているそう。
この問題を回避するには『PCLビルド時の PCL_ONLY_CORE_POINT_TYPES をONにして、pcl_featureのメンバーを減らす』しか方法がないそう。

ただし、これを行うとpcl::PointNormal等の一部のポイントタイプが、今まで通りには使えなくなる。


というわけで、以下では

  • LNK1189エラーの解消方法
  • 今まで通りにポイントタイプを使うための方法

をメモ。

LNK1189エラーの解消方法

  1. cmake-gui で PCL_ONLY_CORE_POINT_TYPES を ON にする
  2. Configure を押す
  3. Generate を押す
  4. 生成された PCL.sln を開いて ALL_BUILD する
    • クリーン・リビルドする必要はなく、単純にビルドでよい

今まで通りにポイントタイプを使うための方法

  1. 今まで作ったプロジェクトに PCL_NO_PRECOMPILE マクロを定義する

CMakeLists.txt内に書いておきたい場合:

add_definitions(-DPCL_NO_PRECOMPILE)

ソースファイル内に書いておきたい場合:

#define PCL_NO_PRECOMPILE

動作確認

下記のコードの PointT, NormalT の typedef を自分が使いたいポイントタイプに書き換えて、1,2行目のコメントを入れ替えて実行してみる。

//#define PCL_NO_PRECOMPILE		// ここを入れ替えて試す
#undef PCL_NO_PRECOMPILE		// 

//#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/features/normal_3d_omp.h>
#include <pcl/filters/extract_indices.h>

typedef pcl::PointXYZINormal PointT;  // 適当に設定
typedef pcl::PointCloud<PointT> PointCloudT;
typedef PointCloudT::Ptr PointCloudPtrT;
typedef PointCloudT::ConstPtr PointCloudConstPtrT;

typedef pcl::PointNormal NormalT;  // 適当に設定
typedef pcl::PointCloud<NormalT> NormalCloudT;
typedef NormalCloudT::Ptr NormalCloudPtrT;
typedef NormalCloudT::ConstPtr NormalCloudConstPtrT;

void main() {
	// Create data
	pcl::IndicesPtr indices(new std::vector<int>);
	PointCloudPtrT cloud_in(new PointCloudT), cloud_out(new PointCloudT);
	NormalCloudPtrT normals(new NormalCloudT);

	// Test filter 1
	pcl::ExtractIndices<PointT> ext;
	ext.setInputCloud(cloud_in);
	ext.setIndices(indices);
	ext.filter(*cloud_out);

	// Test filter 2
	pcl::NormalEstimationOMP<PointT, NormalT> ne;
	ne.setInputCloud(cloud_in);
	ne.setKSearch(5);
	ne.compute(*normals);

	std:system("pause");
}

PCL_NO_PRECOMPILE が未定義だと次のエラーがでる。

2>test.obj : error LNK2001: 外部シンボル ""protected: virtual void __thiscall pcl::NormalEstimation<struct pcl::PointXYZINormal,struct pcl::PointNormal>::computeFeature(class pcl::PointCloud<struct pcl::PointNormal> &)" (?computeFeature@?$NormalEstimation@UPointXYZINormal@pcl@@UPointNormal@2@@pcl@@MAEXAAV?$PointCloud@UPointNormal@pcl@@@2@@Z)" は未解決です。
2>test.obj : error LNK2001: 外部シンボル ""private: virtual void __thiscall pcl::NormalEstimationOMP<struct pcl::PointXYZINormal,struct pcl::PointNormal>::computeFeature(class pcl::PointCloud<struct pcl::PointNormal> &)" (?computeFeature@?$NormalEstimationOMP@UPointXYZINormal@pcl@@UPointNormal@2@@pcl@@EAEXAAV?$PointCloud@UPointNormal@pcl@@@2@@Z)" は未解決です。
2>test.obj : error LNK2001: 外部シンボル ""protected: virtual void __thiscall pcl::ExtractIndices<struct pcl::PointXYZINormal>::applyFilter(class pcl::PointCloud<struct pcl::PointXYZINormal> &)" (?applyFilter@?$ExtractIndices@UPointXYZINormal@pcl@@@pcl@@MAEXAAV?$PointCloud@UPointXYZINormal@pcl@@@2@@Z)" は未解決です。
2>test.obj : error LNK2019: 未解決の外部シンボル "protected: void __thiscall pcl::ExtractIndices<struct pcl::PointXYZINormal>::applyFilterIndices(class std::vector<int,class std::allocator<int> > &)" (?applyFilterIndices@?$ExtractIndices@UPointXYZINormal@pcl@@@pcl@@IAEXAAV?$vector@HV?$allocator@H@std@@@std@@@Z) が関数 "protected: virtual void __thiscall pcl::ExtractIndices<struct pcl::PointXYZINormal>::applyFilter(class std::vector<int,class std::allocator<int> > &)" (?applyFilter@?$ExtractIndices@UPointXYZINormal@pcl@@@pcl@@MAEXAAV?$vector@HV?$allocator@H@std@@@std@@@Z) で参照されました。
2>C:\test\Release\test.exe : fatal error LNK1120: 外部参照 4 が未解決です。