2010-01-12 5 views
12

저는 종종 C 언어 구조체와 상호 작용하는 다른 언어로 코드를 작성해야합니다. 가장 일반적인 방법은 struct 또는 ctypes 모듈을 사용하여 파이썬 코드를 작성하는 것입니다.C 구조체의 필드를 추출하십시오.

그래서 구조체 정의로 가득 찬 .h 파일을 수동으로 읽고이를 파이썬 코드에 복사해야합니다. 이는 시간이 오래 걸리며 오류가 발생하기 쉽고 자주 변경되는 경우 두 정의를 동기화 상태로 유지하기가 어렵습니다.

.h 파일을 가져 와서 해당 구조체 및 해당 필드의 구조화 된 목록을 생성 할 수있는 언어 (C 또는 Python 일 필요는 없음)로 된 도구 또는 라이브러리가 있습니까? 필자는 파이썬에서 구조체 정의를 자동으로 생성하는 스크립트를 작성할 수 있기를 원하며 임의의 C 코드를 처리해야하는 것을 원하지 않습니다. 정규 표현식은 시간의 약 90 %에서 효과적 일 것이고 나머지 10 %는 끝없는 두통을 유발할 것입니다.

+3

"정규 표현식은 시간의 약 90 %에서 효과적 일 것이고 나머지 10 %는 끝없는 두통을 일으킬 것입니다." 정규 표현식을 아주 잘 요약 한 것입니다. 나는 비율을 50/50 정도로 할 것입니다. – captncraig

답변

10

디버깅 (-g)을 사용하여 C 코드를 컴파일하는 경우 pahole (git)을 사용하면 정확한 구조 레이아웃을 사용할 수 있습니다.

 
$ pahole /bin/dd 
… 
struct option { 
     const char *    name;     /*  0  8 */ 
     int      has_arg;    /*  8  4 */ 

     /* XXX 4 bytes hole, try to pack */ 

     int *      flag;     /* 16  8 */ 
     int      val;     /* 24  4 */ 

     /* size: 32, cachelines: 1, members: 4 */ 
     /* sum members: 24, holes: 1, sum holes: 4 */ 
     /* padding: 4 */ 
     /* last cacheline: 32 bytes */ 
}; 
… 

나머지 10 %에 대한 끝없는 두통을 시간의 큰 약 90 %를 작동하고 원인이 바로 C.

0

이 작업에 대한 제 친구는 그가 장부와 함께 사용하는 C 파서를 수행했습니다.

3

인터페이스 코드를 생성하는 Swig 또는 SIP을 보거나 ctypes을 사용하십시오.

5

정규 표현식보다는 구문 분석 할 수 꽤 많이 친절해야한다.

두통은 C 코드에 정규 표현식 작성시 생각지 못한 구문이있는 경우에 발생합니다. 그러면 C가 정규 표현식에 의해 실제로 파싱 될 수 없다는 것을 깨닫고 인생은 재미 있지 않게됩니다. C는보다 적은 트릭을 할 수 있습니다 자신의 간단한 형식을 정의하고, C 헤더 파일과 파일에서 파이썬 인터페이스 코드를 모두 생성 :

주위를 켜십시오 쉽게 그리고

define socketopts 
    int16 port 
    int32 ipv4address 
    int32 flags 

당신은 할 수 있습니다

typedef struct { 
    short port; 
    int ipv4address; 
    int flags; 
} socketopts; 

또한 (당신에게 달려, 그 가능성이 빅 엔디안과 다른 네이티브 엔디안) 세 가지 값을/팩 풀고 struct를 사용하는 파이썬 클래스를 방출 :이 변환 일부 파이썬 쓰기 .

+0

필자는이 점을 분명히 생각했지만 종종 우리는 의사 소통을 위해 사용자 지정 프로토콜을 구현해야하는 다른 회사의 코드를 사용하고 있습니다. 코드를 다시 작성할 수는 없지만 헤더 파일에 액세스 할 수는 없기 때문에이 방법은 isn이 아닙니다. 가능하지 않다. 그러나 C 및 Python 구성 요소를 모두 처음부터 시스템을 구현하는 경우 확실히이 작업을 수행 할 것입니다. –

+0

또한, 필자는 예제가 "port"와 "ipv4address"사이의 플랫폼 종속 패딩을 고려해야하기 때문에 여전히 끔찍한 것으로 나타났습니다. 이 스키마를 사용하여 헤더를 수동으로 DSL로 변환 한 다음 특정 값을 쓰는 방법으로 구조체와 원래 구조체가 동일하다는 것을 확인하는 일부 테스트 (C로 작성)를 자동으로 생성하여 "오류가 발생하기 쉬운"문제를 해결할 수 있습니다 두 구조체의 다양한 필드에 추가 한 다음 memcmping합니다. 그런 다음 동일한 방식으로 Python 코드를 테스트하십시오. 모든 것이 일치하면 좋은 것입니다. –

+1

... 타사에서 DSL로 번역 할 수없는 헤더 파일을 보낸 경우 DSL을 확장하거나 불만을 토로합니다. 그러나 나는 끔찍한 대답을 선호합니다. 모든 패딩 정보가 컴파일러에서 바로 꺼내기 때문입니다. –

1

저는 꽤 큰 프로젝트에서 GCCXML을 성공적으로 사용했습니다. 간단한 파이썬으로 후 처리 할 수있는 C 코드 (구조 포함)의 XML 표현을 얻을 수 있습니다.

1

ctypes-codegen 또는 ctypeslib는 (같은 일이, 내가 생각)하는 ctypes에게 Structure 정의를 생성합니다 (다른 것들, 내가 생각,하지만 난 단지 구조체를 시도) GCCXML를 사용하여 헤더 파일을 구문 분석. 더 이상 지원되지 않지만 일부 경우에는 작동합니다.

관련 문제