我正在寻找一种在两个进程之间共享 pcl::PointCloud 而不使用磁盘上的文件的方法。 特别是,我对使用 boost 共享内存库来实现我的范围感兴趣。
我刚刚为发件人尝试了以下说明:
void * pSharedMemory = ... ; // from wherever
pcl::PointCloud<pcl::PointXYZ>::Ptr ptr = ... ; // from wherever
memcpy ( pSharedMemory , static_cast<void const*>(ptr.get()) , sizeof(pcl::PointCloud<pcl::PointXYZ>) ) ;
以及接收者的以下信息:
template <typename T> nothing ( T* ) { }
void * pSharedMemory = ... ; // from wherever
pcl::PointCloud<pcl::PointXYZ>::Ptr ptr ( static_cast<pcl::PointCloud<pcl::PointXYZ>*>(pSharedMemory) , ¬hing<pcl::PointCloud<pcl::PointXYZ> > ) ; // sets the destructor to do nothing
发送方似乎可以工作,因为我能够从内存中可视化点云,但在客户端,对象已正确创建和填充,但当我尝试访问应包含以下内容的点属性时,出现分段错误云的点。所有其他属性(如宽度、高度……)都填充了正确的值。
如何解决此问题并访问积分结构?或者还有其他方法来实现我的范围吗?
问题在于内部使用指针时,例如在矢量实现中:
using VectorType = std::vector< PointT, Eigen::aligned_allocator< PointT > >;
using CloudVectorType = std::vector< PointCloud< PointT >, Eigen::aligned_allocator< PointCloud< PointT > > >;
这些指针仅在“原始”地址空间中有效,并且首先并不指向共享地址空间内部。即使他们这样做了,内存也可能被映射到每个进程中的不同地址,因此使用它们仍然是未定义的行为。
由于 PCL 不允许您覆盖分配器,这是一个死胡同,因为即使您可以使其使用进程间分配器(内部使用像
boost::interprocess::offset_ptr<>
这样的丰富指针),这些也不容易满足额外的对齐要求特征分配器强加。
非常有可能在共享内存中共享复杂的数据结构,但是构建库时必须考虑到这一点,至少允许您选择/参数化容器/分配器选择。 PCL 目前还不是这样的库。
此时您可以考虑在进程之间序列化数据。这对于您的用例来说可能成本太高,因此在这种情况下您可能需要查看另一个库。