| xCore-SDK 0.7.0 xCore SDK C# API

C# 接口封装说明

C::封装用的是C++/CLI，是用来代替C++托管扩展（Managed C++，下文使用MC++指代）的语言。

# 新增接口和数据结构

和C++类似，在.hpp文件中写函数声明，在.cpp中实现

- 定义在 `BaseRobot`类,`Model`类下面的函数, 在 robot_cli.hpp `BaseRobot` 类下面新增函数声明，在robot_cli.cpp写函数实现
- 定义在 `Robot_T`, `Model_T` (也就是区分轴数的模板类) 下面的，也在 `BaseRobot` 类下面新增函数声明，实现时注意判断实际构造的机型，分别用 `ir3` `ir4` `ir6` `cobot5` `cobot6` `cobot7` 调用C++函数
- 定义在 `BaseCobot` 下面的，在 robot_cli.hpp `Cobot`类下面新增函数
- 定义在 `Cobot` 类下面的, 也在`Cobot`类下面新增。同样地，注意判断实际构造的机型。
- 少数和机型类别绑定的功能，比如setAvoidSingularity(), 只适用于六轴机型，那么在对应的类下面定义
- 新增加的枚举类、数据结构，在data_types_cli.hpp 定义，写必要的构造函数
- 力控指令类，在 force_control_cli新增
- 如果有新增加的class, 可仿照 ForceControl

# 函数实现

简单来讲，每个封装函数完成3件事情：

1. 转换传入的参数，从C::的数据类型转成C++的
2. 通过raw pointer调用C++函数
3. 转换传出的参数

int BaseRobot::checkPath(array<double>^ start_joint, array<CartesianPosition^>^ targets, array<double>^% target_joint_calculated, ErrorCode^% ec)
{
error_code _ec;
std::vector<double> _start_joint = convertArrayToVector(start_joint);
std::vector<double> _target_joint_calculated;
std::vector<rokae::CartesianPosition> _targets;
for each (CartesianPosition^ target in targets)
{
_targets.emplace_back(convertCartesianPosition(target));
}
auto ret = robot->checkPath(_start_joint, _targets, _target_joint_calculated, _ec);
convertErrorCode(_ec, ec);
target_joint_calculated = convertVectorToArray(_target_joint_calculated);
return ret;
}

以checkPath函数为例，start_joint 和 targets是传入参数，分别转换成C++中的 `std::vector<double>` , `std::vector<CartesianPosition>`

然后调用原始C++函数。

target_joint_calculated 和 ec是传出的参数，分别转换成array<double>^ 和自定义的 ErrorCode

converter_cli.hpp中写了一些常用的转换函数

# 数据类型对应关系

## 基础数据类型

C++数据类型 | C++/CLI数据类型 | 转换说明
--- | --- | ---
int, double, float,bool |  | 不需要转换
uint8_t, unsigned char | Byte | 不需要转换
int8_t, char | SByte | 不需要转换
std::string | System.String^ | 见convertString()
std::vector<T>, std::array<T> | array<T>^ | 遍历数组，逐个元素转换

注: 早期部分vector转换成了List, 不再建议使用

## 自定义数据类型

基本上，自定义的数据类型都定义为引用类型(ref class)。参数类型后面带的 `^` 符号就代表这是一个引用类型。转换方式参考converter_cli.cpp

## 传入和传出参数

传入参数无需特殊声明。传出参数有两种标注方式：

1. 在参数类型后面加 `%`, 比如上方示例里的 `array<double>^% target_joint_calculated`
2. 在参数类型前面加 `[Out]` 标志，同时加 `%`, 比如所有的错误码 [Out] ErrorCode^% ec。和上一种的区别是函数实现里要负责创建该参数的对象。比如，每个函数里都会执行这样一行

ec = gcnew ErrorCode(_ec.value(), gcnew System::String(_ec.message().data()));

`gcnew` 就是用于分配内存并创建对象

一般使用第一种方式标注就行

## 模板函数

C::中的泛函数和C++中的概念不太一样，所以模板函数要把支持的参数类型都声明定义一遍。参考 writeRegister

# 函数注释

每个函数都要在.hpp写函数注释，仿照已有的写就行