一个传感器的SDK(C#)

  • Post author:
  • Post category:案例
  • Post comments:0评论

上一篇(一个传感器的SDK(C++) – Zla (fromzla.cn))介绍了一个传感器SDK C++部分,但是C++的库就项目使用而言不太够用,有些项目开发也会使用C#实施,C#调用C++可以使用DllImport 或者编一个CLR项目,这里做一个CLR的封装

创建一个CLR项目(关于CLI项目,参考:使用 C++/CLI 进行 .NET 编程 | Microsoft Learn

SensorSDKDotNet.h

#pragma once
//C++ SDK的头文件
#include "../SharedLibs/SensorSDK/include/sensor_api.h"

using namespace System;

namespace sensor_sdk_dot_net {
	public delegate void SensorDataCallback(int data);
	public delegate void SensorLogCallback(String^ log_str);

	public ref class sensor_sdk sealed
	{
	private:
		void* sensor_;

	public:
		sensor_sdk();
		~sensor_sdk();
		bool open();
		bool close();
		bool execute_cmd(String^ cmd_str);
		int get_int_value(String^ param_name);
		bool set_int_value(String^ param_name, int value);
		bool register_data_callback(SensorDataCallback^ data_callback);
		bool register_log_callback(SensorLogCallback^ log_callback);
	};
}

SensorSDKDotNet.cpp

#include "SensorSDKDotNet.h"

using namespace Runtime::InteropServices;

sensor_sdk_dot_net::sensor_sdk::sensor_sdk()
{
	const pin_ptr<void*> handle = &this->sensor_;
	const auto is_succeed = sensor_create(handle);
	if (!is_succeed)
		throw gcnew  ApplicationException("Instantiation sensor sdk fail!");
}

sensor_sdk_dot_net::sensor_sdk::~sensor_sdk()
{
	sensor_destroy(sensor_);
}

bool sensor_sdk_dot_net::sensor_sdk::open()
{
	return sensor_open(sensor_);
}

bool sensor_sdk_dot_net::sensor_sdk::close()
{
	return  sensor_close(sensor_);
}

bool sensor_sdk_dot_net::sensor_sdk::execute_cmd(String^ cmd_str)
{
	const auto cmd = static_cast<char*>(safe_cast<void*>(Marshal::StringToHGlobalAnsi(cmd_str)));
	const auto is_succeed = sensor_execute_cmd(sensor_, cmd);
	Marshal::FreeHGlobal(IntPtr(cmd));
	return is_succeed;
}

int sensor_sdk_dot_net::sensor_sdk::get_int_value(String^ param_name)
{
	const auto name = static_cast<char*>(safe_cast<void*>(Marshal::StringToHGlobalAnsi(param_name)));
	int value = -1;
	const auto is_succeed = sensor_get_int_value(sensor_, name, &value);
	Marshal::FreeHGlobal(IntPtr(name));
	return value;
}

bool sensor_sdk_dot_net::sensor_sdk::set_int_value(String^ param_name, const int value)
{
	const auto name = static_cast<char*>(safe_cast<void*>(Marshal::StringToHGlobalAnsi(param_name)));
	const auto is_succeed = sensor_set_int_value(sensor_, name, value);
	Marshal::FreeHGlobal(IntPtr(name));
	return is_succeed;
}

void _stdcall sensor_data_callback_func(const int data, void* p_user)
{
	auto callback = Marshal::GetDelegateForFunctionPointer<sensor_sdk_dot_net::SensorDataCallback^>(IntPtr(p_user));
	callback(data);
}

void _stdcall sensor_log_callback_func(char* sensor_log, void* p_user)
{
	auto callback = Marshal::GetDelegateForFunctionPointer<sensor_sdk_dot_net::SensorLogCallback^>(IntPtr(p_user));
	callback(Marshal::PtrToStringAnsi(IntPtr(sensor_log)));
}

bool sensor_sdk_dot_net::sensor_sdk::register_data_callback(SensorDataCallback^ data_callback)
{
	IntPtr callback_func = Marshal::GetFunctionPointerForDelegate(data_callback);
	const auto is_succeed = sensor_register_data_callback(sensor_, sensor_data_callback_func, callback_func.ToPointer());
	return is_succeed;
}

bool sensor_sdk_dot_net::sensor_sdk::register_log_callback(SensorLogCallback^ log_callback)
{
	IntPtr callback_func = Marshal::GetFunctionPointerForDelegate(log_callback);
	const auto is_succeed = sensor_register_log_callback(sensor_, sensor_log_callback_func, callback_func.ToPointer());
	return is_succeed;
}

创建一个C#控制台项目进行测试,此处运行时要注意运行目录要包含c++库的dll和clr库的dll

Program.cs

using System;
using sensor_sdk_dot_net;

namespace CSDemo
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            var sensor = new sensor_sdk();
            sensor.register_data_callback(data =>
            {
                Console.WriteLine($"传感器数据:{data}");
            });
            sensor.register_log_callback(log =>
            {
                Console.WriteLine($"传感器日志:{log}");
            });
            Console.WriteLine("q - 退出");
            Console.WriteLine("open - 打开传感器");
            Console.WriteLine("close - 关闭传感器");
            Console.WriteLine("cmd - 执行命令(当前支持 collect 命令)");
            Console.WriteLine("read - 读参数");
            Console.WriteLine("write - 写参数");
            Console.Write("键入指令:");
            var cmd = Console.ReadLine();
            while (true)
            {
                if (cmd is "q")
                    break;
                switch (cmd)
                {
                    case "open":
                        sensor.open();
                        break;

                    case "close":
                        sensor.close();
                        break;

                    case "cmd":
                        Console.Write("命令:");
                        cmd = Console.ReadLine();
                        sensor.execute_cmd(cmd);
                        break;

                    case "read":
                        Console.Write("输入参数名:");
                        var readParamName = Console.ReadLine();
                        var readValue = sensor.get_int_value(readParamName);
                        Console.WriteLine($"Get param {readParamName} value is {readValue}");
                        break;

                    case "write":
                        Console.Write("输入参数名:");
                        var writeParamName = Console.ReadLine();
                        Console.Write("输入参数值:");
                        var writeStr = Console.ReadLine();
                        var isValid = int.TryParse(writeStr, out var writeValue);
                        if (!isValid)
                            Console.WriteLine("Input is invalid");
                        sensor.set_int_value(writeParamName, writeValue);
                        Console.WriteLine($"Get param {writeParamName} value is {writeValue}");
                        break;
                }
                Console.Write("键入指令:");
                cmd = Console.ReadLine();
            }
        }
    }
}

发表回复