Skip to content

6.3 C++11 接入 C99 接口

概述

C++11 项目可以直接通过 extern "C" 调用 C99 SDK 头文件和导入库。这样做的核心价值是保持接口扁平、依赖最小,并且继续使用 ArmHandle* 这套 C 风格生命周期。

适用场景

场景说明
最小依赖只依赖 C99 公开头和 C/C++ 标准库
遗留工程项目还停留在 C++11,暂不适合切换到 C++17
平台兼容需要扁平 ABI 和手动生命周期管理

头文件引入

cpp
extern "C" {  // C++11 工程中按 C 链接方式引入 C99 SDK 头文件
#include "c_arm_api.h"  // 引入 C99 SDK 总头文件
}  // 结束 C 链接声明

最小接入示例

示例代码

cpp11/c99_connect_get_version/src/main.cpp
cpp
#include <stdio.h>

extern "C" {
#include "c_arm_api.h"
}

int main(void)
{
    // [ZH] 本示例直接在源码中写死连接地址,不解析命令行参数。
    // [EN] This example hard-codes the connection addresses in the source code and does not parse command-line arguments.
    ArmHandle* handle = Arm_Create();
    if (handle == NULL) {
        printf("[cpp11_c99_connect_get_version] 创建句柄失败 / Failed to create the handle\n");
        return 1;
    }

    // [ZH] 连接机器人。
    // [EN] Connect to the robot.
    const int connectRet = Arm_Connect(handle, "10.27.1.2", "10.27.1.102");
    if (connectRet != 0) {
        printf("[cpp11_c99_connect_get_version] 连接失败 / Connect failed, 状态码 / Status code: %d\n", connectRet);
        Arm_Destroy(handle);
        return 1;
    }
    printf("[cpp11_c99_connect_get_version] 机器人连接成功 / Robot connected successfully\n");

    // [ZH] 读取控制器版本。
    // [EN] Read the controller version.
    char version[128] = {0};
    const int versionRet = Arm_Info_GetControllerVersion(
        handle,
        version,
        sizeof(version)
    );
    if (versionRet != 0) {
        printf("[cpp11_c99_connect_get_version] 获取版本失败 / Get version failed, 状态码 / Status code: %d\n", versionRet);
        Arm_Disconnect(handle);
        Arm_Destroy(handle);
        return 1;
    }
    printf("[cpp11_c99_connect_get_version] 控制器版本 / Controller version: %s\n", version);

    // [ZH] 断开连接并销毁句柄。
    // [EN] Disconnect and destroy the handle.
    Arm_Disconnect(handle);
    Arm_Destroy(handle);
    printf("[cpp11_c99_connect_get_version] 示例结束 / Example finished\n");
    return 0;
}

CMake 配置

对应完整 CMake 文件:

cpp11/c99_connect_get_version/CMakeLists.txt
txt
cmake_minimum_required(VERSION 3.20)
project(c99_connect_get_version LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 11)
add_executable(c99_connect_get_version
    src/main.cpp
)
set_target_properties(c99_connect_get_version PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/output")
target_include_directories(c99_connect_get_version PRIVATE src dependency/include)
target_compile_options(c99_connect_get_version PRIVATE /utf-8)
target_link_libraries(c99_connect_get_version PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/dependency/lib/AgilebotCppSdk.lib")

编译与运行

powershell
powershell -ExecutionPolicy Bypass -File example/cpp11/c99_connect_get_version/build/build.ps1

对应构建脚本:

cpp11/c99_connect_get_version/build/build.ps1
ps1
param()

chcp 65001 > $null
[Console]::OutputEncoding = [Text.Encoding]::UTF8

# 在示例脚本目录下执行,统一使用相对路径访问工程和产物。
Set-Location $PSScriptRoot
# 清理上一次拷贝的 SDK 依赖与示例运行产物,避免旧 DLL 干扰当前验证。
Remove-Item -Recurse -Force ..\dependency -ErrorAction Ignore
Remove-Item -Recurse -Force ..\output -ErrorAction Ignore
powershell -ExecutionPolicy Bypass -File ..\..\..\build\prepare_dependency.ps1 -Package c99
# 配置并编译当前独立示例工程。
cmake -S .. -B ..\buildcache -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_CXX_COMPILER=clang-cl -DCMAKE_LINKER_TYPE=LLD

if (Test-Path ..\buildcache\compile_commands.json) {
    Copy-Item -Force ..\buildcache\compile_commands.json ..\compile_commands.json
}
cmake --build ..\buildcache
powershell -ExecutionPolicy Bypass -File ..\..\..\build\run_example.ps1 -Executable ..\output\c99_connect_get_version.exe

说明:

  • 编译脚本会自动从 output/release/c99-sdk/ 准备依赖。
  • 运行前如需切换设备,修改示例中的控制器地址和示教器地址。

线程模型

C++11 通过 C99 接口使用 SDK 时,线程模型与 C99 完全一致:

  • 同步调用在调用线程执行
  • 周期任务在会话专用网络线程执行,例如 Arm_Info_AcquireAccess()Arm_Jogging_ContinuousMove()
  • 订阅回调在 WebSocket 消息到达时触发

详见 1.3 线程模型。

与 C++17 SDK 对比

特性C++11 + C99C++17 SDK
入口形态extern "C" + ArmHandle*Arm 对象
返回方式状态码 + out 参数STATUS_CODE / std::pair
资源管理手动 DestroyRAII 自动释放
容器返回调用方自己管理数组std::vector / std::string
适用范围老工程、最小依赖集成新工程、对象式封装

示例列表

example/cpp11 目录提供与 example/c99 对齐的示例代码

示例说明
arm_connect_disconnectCore create/connect/disconnect/destroy
info_basicArm Info 全部接口
alarm_queryArm Alarm 全部接口
motion_basicArm Motion 全部接口
program_executionArm Program、BasScript、ArmProgramPose
registers_basicArm Registers 全部接口
signals_basicArm Signals 全部接口
trajectory_basicArm Trajectory 与 Arm RealTimeTrajectory
file_manager_basicArm FileManager 全部接口
coordinate_system_basicArm CoordinateSystem 全部接口
modbus_basicArm Modbus 全部接口
jogging_basicArm Jogging 全部接口
extension_basicArm Extension 全部接口
sub_pub_basicArm SubPub 全部接口
c99_connect_get_version最小接入闭环示例

注意事项

  1. 头文件必须放在 extern "C" 里。
  2. ArmHandle* 需要手动 Arm_Destroy() 释放。
  3. 所有接口都要检查返回值。
  4. 同一 ArmHandle* 不要被多个线程并发乱用。