Skip to content

6.2 C# 接入 C99 SDK

概述

C# 应用可通过 DllImport (P/Invoke) 调用 C99 SDK 动态库,实现跨语言集成。

6.2.1 环境准备

依赖说明
.NETFramework 4.5+ 或 .NET Core 3.1+
C99 SDKc_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 注意事项

  1. 调用约定:C99 SDK 使用 cdecl ,需指定 CallingConvention = CallingConvention.Cdecl
  2. 平台目标:确保 C# 项目平台目标与 DLL 一致(x64)
  3. DLL 路径:确保 DLL 在可搜索路径中
  4. 线程安全:同一句柄不能跨线程并发访问
  5. BasScript Builder:C99 暴露 ArmBasScriptHandleArmBasExtraParamHandle ,C# 侧可封装为对象化脚本构造接口
  6. Builder 便捷封装Arm_BasScript_SetName / AppendLine(s)Arm_BasValue_* 可映射为 C# 对象方法和静态工厂