6.1 Python Accessing C99 SDK
Overview
Python applications can call C99 SDK dynamic library via ctypes for cross-language integration.
6.1.1 Prerequisites
| Dependency | Description |
|---|---|
| Python | 3.6+ |
| C99 SDK | c_arm_api.dll (Windows) or libc_arm_api.so (Linux) |
6.1.2 Minimal Example: Connect and Disconnect
python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import ctypes
# Load C99 SDK dynamic library
arm_api = ctypes.CDLL("c_arm_api.dll")
# Create handle
handle = arm_api.Arm_Create()
# Connect to robot
ret = arm_api.Arm_Connect(handle, b"10.27.1.2", b"10.27.1.102")
print(f"Connect result: {ret}")
# Disconnect
arm_api.Arm_Disconnect(handle)
# Destroy handle
arm_api.Arm_Destroy(handle)
print("Done")6.1.3 Object-Oriented Wrapper (Facade Pattern)
You can create an Arm class that wraps C99 functions into a Pythonic object-oriented API:
python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import ctypes
class Arm:
"""Robot control facade class"""
def __init__(self, dll_path: str = "c_arm_api.dll"):
self._api = ctypes.CDLL(dll_path)
self._setup_signatures()
self._handle = None
def _setup_signatures(self):
"""Set up function signatures"""
self._api.Arm_Create.argtypes = []
self._api.Arm_Create.restype = ctypes.c_void_p
self._api.Arm_Destroy.argtypes = [ctypes.c_void_p]
self._api.Arm_Destroy.restype = None
self._api.Arm_Connect.argtypes = [ctypes.c_void_p, ctypes.c_char_p, ctypes.c_char_p]
self._api.Arm_Connect.restype = ctypes.c_int
self._api.Arm_Disconnect.argtypes = [ctypes.c_void_p]
self._api.Arm_Disconnect.restype = None
def connect(self, controller_ip: str, teach_panel_ip: str = None) -> None:
"""Connect to robot"""
if self._handle is None:
self._handle = self._api.Arm_Create()
ret = self._api.Arm_Connect(
self._handle,
controller_ip.encode('utf-8'),
teach_panel_ip.encode('utf-8') if teach_panel_ip else None
)
if ret != 0:
raise RuntimeError(f"Connect failed: {ret}")
def disconnect(self) -> None:
"""Disconnect"""
if self._handle:
self._api.Arm_Disconnect(self._handle)
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.disconnect()
if self._handle:
self._api.Arm_Destroy(self._handle)
return False
# Usage example
with Arm() as arm:
arm.connect("10.27.1.2", "10.27.1.102")
print("Connected successfully")6.1.4 Notes
- String Encoding: Input strings need
encode('utf-8')to convert tobytes - DLL Path: Ensure DLL is in searchable path
- Thread Safety: Same handle cannot be accessed concurrently across threads
- BasScript Builder: C99 now also provides
ArmBasScriptHandle/ArmBasExtraParamHandle, so Python bindings can wrap script construction APIs instead of manually buildingconst char**BAS line arrays - Builder Convenience Wrappers:
Arm_BasScript_SetName/AppendLine(s)andArm_BasValue_*are good candidates for Python-side object methods and factory helpers, avoiding manualtag/intValue/doubleValue/stringValue