在c#中使用pcl的步骤

1 篇文章 0 订阅

模拟是最需要的才能,从模仿中学习。

在c#中使用pcl的步骤

在pcl就使用这种方式了,因为CLR的方式行不通,CLR(中间语言支持库)需要知道源文件,而pcl的原文件超级复杂,并且不一定导出的时候就是CLR的那种导出方式,所以这里的关注点就是采用c语言形式导出动态库的方式,其他不用管。

一和二是导出不需要传复杂参数的方式,或者是之后不需要咋使用

一、c++库的静态库导出

导出动态库的时候好像不能在多处include头文件,不然会出现重定义,这与平时的运行程序会有点不一样。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KnEDk2A2-1665283361727)(重定义.png)]

步骤:define定义导入导出——>原本实现——>在原本实现基础上定义导出函数,在函数中调用“原本实现”的函数,以及传入相关的类参数

  1. 防止重定义的define

    #ifndef PCLFUNC_EXPORT_H
    #define PCLFUNC_EXPORT_H
    
    //相关定义
    
    #endif // !PCLFUNC_EXPORT_H
    
  2. define定义导入导出

    #ifndef DLL_IMPORT
    #define TESTDLL_API __declspec(dllexport)
    #else
    #define TESTDLL_API __declspec(dllimport)
    
  3. 原本实现

    //主要写自己的实现
    #include <pcl/io/pcd_io.h>
    #include <pcl/point_types.h>
    #include<string>
    using namespace std;
    using namespace pcl::io;
    
    class  PCLFuncExport
    {
    public:
    	PCLFuncExport();
    	~PCLFuncExport();
    
    	pcl::PointCloud<pcl::PointXYZ>::Ptr getPclPoint();
    	void setPclPint(string path);
    	int readPcdFile(string path, pcl::PointCloud<pcl::PointXYZ>::Ptr cloud);
    
    private:
    	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud;
    };
    
  4. 在原本实现基础上定义导出函数,在函数中调用“原本实现”的函数,以及传入相关的类参数

    • 主要是通过我们自己写的方法去调用第三方库pcl库,不然我们不知道第三方库是怎么封装的,而且第三方库的封装可能也不符合我们的要求,所以这样封装调用是比较方便的,不过传递参数的类以及对象需要在c#中对应起来,这里通过开源的pcl c#包解决的
    extern "C" TESTDLL_API  PCLFuncExport* dllGetObj() { return new PCLFuncExport(); };
    extern "C" TESTDLL_API int dllReadPcd(PCLFuncExport * pcl,string path, pcl::PointCloud<pcl::PointXYZ>::Ptr cloud) {
    	return pcl->readPcdFile(path, cloud);
    }
    extern "C" TESTDLL_API void dllSetPcl(PCLFuncExport * pcl, string path) {
    	pcl->setPclPint(path);
    }
    extern "C" TESTDLL_API void dllDeletePclFuncExport(PCLFuncExport * pcl) {
    	delete pcl;
    }
    

二、c#类库的封装调用

新建一个c# 类库项目,如图所示
在这里插入图片描述

[DllImport("PCLCppDll.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public extern static int dllReadPcd(IntPtr pcl, [MarshalAs(UnmanagedType.LPStr)] string path,IntPtr cloud);
  1. 约定好字符集以及调用栈和清空方式。
  2. 字符串采用[MarshalAs(UnmanagedType.LPStr)] string path
  3. 数组以及类直接都是用IntPtr
  4. 以公共、extern以及静态方式声明:public extern static

类中以首字母大写的方式去调用其结果,这里和一般的方式一样,并不需要注意什么

public int ReadPcd(IntPtr pcl, string path, IntPtr cloud)
{
	return dllReadPcd(pcl,path,cloud);
}

三、c#中对其的使用

将刚刚类库的包以及pcl的动态库进行导入,可以看到程序集增加进去了:

在这里插入图片描述

在程序中调用类库有的方法

//调用类库

使用pcl csharp包

导入包

//增添的命名空间
using PclSharp.IO;
using PclSharp;

将动态库以及类库包放入bin路径中
在这里插入图片描述

调用方法:

private void button1_Click(object sender, EventArgs e)
        {
            using (var cloud = new PointCloudOfXYZ())
            using (var writer = new PCDWriter())
            using (var pcdReader = new PCDReader())
            {
                if (pcdReader.Read("E:/pcl/test/saddle.pcd", cloud) < 0)
                {
                    MessageBox.Show("没读取成功");
                }
                else
                {
                    MessageBox.Show("点云数据读取成功");

                }

            }
        }

完整源代码:

using System;
using System.Windows.Forms;

//增添的命名空间
using PclSharp.IO;
using PclSharp;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }


        private void button1_Click(object sender, EventArgs e)
        {
            using (var cloud = new PointCloudOfXYZ())
            using (var writer = new PCDWriter())
            using (var pcdReader = new PCDReader())
            {
                if (pcdReader.Read("E:/pcl/test/saddle.pcd", cloud) < 0)
                {
                    MessageBox.Show("没读取成功");
                }
                else
                {
                    MessageBox.Show("点云数据读取成功");

                }

            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }
    }
}

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值