6.1 Python에서 C99 SDK 연동
개요
Python 애플리케이션은 ctypes 를 통해 C99 SDK 동적 라이브러리를 호출하여 언어 간 통합을 구현할 수 있습니다.
6.1.1 환경 준비
| 의존성 | 설명 |
|---|---|
| Python | 3.6+ |
| C99 SDK | c_arm_api.dll (Windows) 또는 libc_arm_api.so (Linux) |
6.1.2 최소 예제: 연결 및 연결 해제
python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import ctypes
# C99 SDK 동적 라이브러리를 로드합니다.
arm_api = ctypes.CDLL("c_arm_api.dll")
# 핸들을 생성합니다.
handle = arm_api.Arm_Create()
# 로봇에 연결합니다.
ret = arm_api.Arm_Connect(handle, b"10.27.1.2", b"10.27.1.102")
print(f"연결 결과: {ret}")
# 연결을 해제합니다.
arm_api.Arm_Disconnect(handle)
# 핸들을 파괴합니다.
arm_api.Arm_Destroy(handle)
print("완료")6.1.3 객체 지향 래퍼(퍼사드 패턴)
Arm 클래스를 만들어 C99 함수를 Pythonic한 객체 지향 API로 래핑할 수 있습니다.
python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import ctypes
class Arm:
"""로봇 제어 퍼사드 클래스"""
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):
"""함수 시그니처를 설정합니다."""
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:
"""로봇에 연결합니다."""
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"연결 실패: {ret}")
def disconnect(self) -> None:
"""연결을 해제합니다."""
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
# 사용 예제
with Arm() as arm:
arm.connect("10.27.1.2", "10.27.1.102")
print("연결 성공")6.1.4 주의 사항
- 문자열 인코딩: 입력 문자열은
encode('utf-8')로bytes로 변환해야 합니다. - DLL 경로: DLL이 검색 가능한 경로에 있는지 확인합니다.
- 스레드 안전: 같은 핸들을 여러 스레드에서 동시에 접근할 수 없습니다.
- BasScript Builder: C99는
ArmBasScriptHandle/ArmBasExtraParamHandle을 제공하므로, Python 바인딩 계층에서 스크립트 구성 인터페이스를 객체로 래핑할 수 있습니다. - Builder 편의 래퍼:
Arm_BasScript_SetName/AppendLine(s)및Arm_BasValue_*는 Python 객체 메서드와 팩토리 함수로 매핑할 수 있습니다.