6.2 C# 接入 C99 SDK
概述
C# 应用可通过 DllImport (P/Invoke) 调用 C99 SDK 动态库,实现跨语言集成。
6.2.1 环境准备
| 依赖 | 说明 |
|---|---|
| .NET | Framework 4.5+ 或 .NET Core 3.1+ |
| C99 SDK | c_arm_api.dll (Windows) |
6.2.2 最小示例:连接与断开
csharp
using System;
using System.Runtime.InteropServices;
class Program
{
[DllImport("c_arm_api.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr Arm_Create();
[DllImport("c_arm_api.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void Arm_Destroy(IntPtr handle);
[DllImport("c_arm_api.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int Arm_Connect(IntPtr handle, string controllerIp, string teachPanelIp);
[DllImport("c_arm_api.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void Arm_Disconnect(IntPtr handle);
static void Main(string[] args)
{
// 创建句柄
IntPtr handle = Arm_Create();
// 连接机器人
int ret = Arm_Connect(handle, "10.27.1.2", "10.27.1.102");
Console.WriteLine($"连接结果: {ret}");
// 断开连接
Arm_Disconnect(handle);
// 销毁句柄
Arm_Destroy(handle);
Console.WriteLine("完成");
}
}6.2.3 面向对象封装(外观模式)
可以创建一个 Arm 类,将 C99 函数封装成 C# 面向对象 API:
csharp
using System;
using System.Runtime.InteropServices;
public class Arm : IDisposable
{
private const string DllName = "c_arm_api.dll";
private IntPtr _handle;
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr Arm_Create();
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
private static extern void Arm_Destroy(IntPtr handle);
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
private static extern int Arm_Connect(IntPtr handle, string controllerIp, string teachPanelIp);
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
private static extern void Arm_Disconnect(IntPtr handle);
public void Connect(string controllerIp, string teachPanelIp = null)
{
if (_handle == IntPtr.Zero)
_handle = Arm_Create();
int ret = Arm_Connect(_handle, controllerIp, teachPanelIp);
if (ret != 0)
throw new InvalidOperationException($"连接失败: {ret}");
}
public void Disconnect()
{
if (_handle != IntPtr.Zero)
Arm_Disconnect(_handle);
}
public void Dispose()
{
Disconnect();
if (_handle != IntPtr.Zero)
{
Arm_Destroy(_handle);
_handle = IntPtr.Zero;
}
}
}
// 使用示例
using (var arm = new Arm())
{
arm.Connect("10.27.1.2", "10.27.1.102");
Console.WriteLine("连接成功");
}6.2.4 注意事项
- 调用约定:C99 SDK 使用
cdecl,需指定CallingConvention = CallingConvention.Cdecl - 平台目标:确保 C# 项目平台目标与 DLL 一致(x64)
- DLL 路径:确保 DLL 在可搜索路径中
- 线程安全:同一句柄不能跨线程并发访问
- BasScript Builder:C99 暴露
ArmBasScriptHandle与ArmBasExtraParamHandle,C# 侧可封装为对象化脚本构造接口 - Builder 便捷封装:
Arm_BasScript_SetName/AppendLine(s)与Arm_BasValue_*可映射为 C# 对象方法和静态工厂