2012-12-10 2 views
7

헤더 파일에 정의 된 프로 시저의 빈 구현을 생성하려고합니다. 이상적으로는 포인터에 대해서는 NULL을, 정수에 대해서는 0을 반환해야하며, 이상적인 세계에서는 호출 된 함수를 stderr에 출력해야합니다.헤더에서 C 코드 자동 생성

이 동기는 복잡한 기존 API (헤더 파일)의 하위 집합을 다른 라이브러리에 적용하는 래퍼를 구현해야한다는 것입니다. API의 프로 시저 중 소수만 위임해야하지만 명확하지는 않습니다. 따라서 반복적 인 접근 방법을 사용하여 자동 생성 래퍼를 실행하고, 호출 된 내용을 확인하고, 위임을 통해 구현하고 반복합니다.

나는 Automatically generate C++ file from header?을 보았지만 대답은 C++과 관련이 있습니다.

그래서 질문이 필요한 사람들은 간단한 용어로 철자가 틀린데 어떻게 헤더 파일이 주어지면 이러한 구현을 자동화 할 수 있습니까? 기존 도구를 선호합니다 - 현재 가장 간단한 해결책은 pycparser를 사용하는 것입니다.

업데이트 감사합니다. 둘 다 좋은 답변입니다. 또한 현재 내 해킹을 게시했습니다.

+0

지금까지 질문을 한 것이 아니지만 지금 할 수있는 기존 도구를 묻는 것 같습니다. 불행히도 나는 어떤 도구를 모르지만, 파이썬 (또는 다른 고수준 언어) 구현을 수행하기에 충분할만큼 기본 소리가 들립니까? – Jite

+0

질문을 명확히했습니다. 예, 제가 이것을 할 수있는 프로그램을 작성할 수 있습니다. 하지만 그것은 사소한 것이 아닙니다. 예를 들어 괜찮은 파서가 필요합니다. 헤더가 충분히 크고 충분히 복잡하기 때문에, ad-hoc regexp 기반 kludge는 시간 낭비가 될 것입니다. –

+0

안녕하세요, 프로세스를 쉽게 반복 할 수 있어야합니까? 예를 들어, 새 버전의 API가 출시되면 스텁 구현을 업데이트 할 수 있기를 원하십니까? – OlduwanSteve

답변

1

UML 모델링 도구는 선택한 언어로 기본 구현을 생성 할 수 있습니다. 일반적으로 소스 코드 (C 헤더 포함) 가져 오기에 대한 지원도 있습니다. 헤더를 가져 와서 소스 코드를 생성 해 볼 수 있습니다. 저는 개인적으로 Enterprise Architect의 경험을 갖고 있으며이 두 가지 작업을 모두 지원합니다.

+0

아, 예, 아마도 이것을 할 것입니다 (인쇄 문은 아님). 아마도 유료 버전 일 수도 있고 수년간 면허가 없었습니다. 그것을 확인할 것입니다. 감사. –

+0

나는이 도구를 할 수있는 무료 도구가 있다고 믿는다. 구글에게 – SomeWittyUsername

+0

무료 uml 도구는 몹시 빨려 들었다. (단지 uml을 원하는 클라이언트가 없다.) 변경되었을 수 있습니다. 볼 것이다. –

1

경고 :이 경험이 없으므로 답을 찾을 수 없습니다.

단위 테스트를 위해 조롱 한 프레임 워크를 사용하는 것이 좋을 것 같습니다. 이러한 프레임 워크의 예는 다음과 같습니다. cmock

프로젝트 페이지는 헤더에서 코드를 생성 할 것을 제안합니다. 그런 다음 코드를 가져 와서 조정할 수 있습니다.

+0

그것은 재미있는 아이디어입니다, 감사합니다. 나는 현재 내가 필요로하는 형식으로 헤더를 얻기 위해 cpp와 싸우는 중이지만,이 방법에 대해 더 많이 생각할 것이다. –

2

그래서 나는 아마도 이것이 일반적으로 가장 좋은 아이디어라고 생각하기 때문에 "답변"으로 ea 제안을 표시 할 것입니다. 비록 내가 그 라이브러리 제안은 테스트 실패에 의해 주도되었다 tdd 접근 방식에서 아주 잘 작동 할 것이라고 생각하지만, 나는 그것을 시도 끝낼 수 있습니다. 하지만 당분간은 대화 형 방식으로 작동하는 더 빠르고 더 진한 접근 방식이 필요합니다. (문제의 라이브러리는 다른 대화 형 프로그램을 위해 동적으로로드 된 플러그인이며 API 호출 순서를 리버스 엔지니어링하려고합니다 ...)

그래서 내가 끝낸 것은 pycparse를 호출하는 python 스크립트를 작성하는 것이 었습니다. 나는 다른 사람들을 돕기 위해 여기에 포함 시키겠다. 그러나 그것은 일반적이지 않다. (예를 들어, 모든 함수가 int를 반환한다고 가정하고 typedef 내부에서 func def를 피하기 위해 해킹을한다.)

from pycparser import parse_file 
from pycparser.c_ast import NodeVisitor 


class AncestorVisitor(NodeVisitor): 

    def __init__(self): 
     self.current = None 
     self.ancestors = [] 

    def visit(self, node): 
     if self.current: 
      self.ancestors.append(self.current) 
     self.current = node 
     try: 
      return super(AncestorVisitor, self).visit(node) 
     finally: 
      if self.ancestors: 
       self.ancestors.pop(-1) 


class FunctionVisitor(AncestorVisitor): 

    def visit_FuncDecl(self, node): 
     if len(self.ancestors) < 3: # avoid typedefs 
      print node.type.type.names[0], node.type.declname, '(', 
      first = True 
      for param in node.args.params: 
       if first: first = False 
       else: print ',', 
       print param.type.type.names[0], param.type.declname, 
      print ')' 
      print '{fprintf(stderr, "%s\\n"); return 0;}' % node.type.declname 


print '#include "myheader.h"' 
print '#include <stdio.h>' 
ast = parse_file('myheader.h', use_cpp=True) 
FunctionVisitor().visit(ast)