2012-12-10 24 views
7

ヘッダーファイルで定義されたプロシージャの空の実装を生成します。理想的には、ポインタの場合はNULL、整数の場合は0などを返し、理想的な世界では関数が呼び出されたstderrにも出力します。ヘッダーからCコードを自動的に生成

これは、複雑な既存のAPI(ヘッダーファイル)のサブセットを別のライブラリに適合させるラッパーを実装する必要があることを意味します。少数のAPIのプロシージャしか委任する必要がありますが、どのプロシージャが委譲されているのかは明らかではありません。ですから、私はこの自動生成ラッパーに対して実行し、何が呼び出されているのかを見て、委譲でそれを実装し、繰り返す反復的なアプローチを使いたいと考えています。

私はAutomatically generate C++ file from header?を見ましたが、答えはC++固有のようです。

質問が必要な人には、簡単な言葉で言いますと、ヘッダファイルを指定してそのような実装の生成を自動化するにはどうすればよいですか?私は既存のツールを好むでしょう - 私の現在の最良の推測は単純な解決策でpycparserを使用しています。

更新ありがとうございました。どちらも良い答えです。また、私の現在のハックを掲載しました。

+0

これまでのところ、実際に質問はされていませんが、これを行うための既存のツールをお探しですか?残念ながら、私はどのツールも知らないのですが、それを解決するための素早いPython(または他の高水準言語)実装を行うのに十分な基本と聞こえますか? – Jite

+0

私は質問を明確にしました。はい、私はこれを行うためのプログラムを書くことができます。しかし、それは自明ではありません - 例えば、まともなパーサーが必要です。ヘッダーは十分に大きく、複雑なので、アドホックな正規表現ベースのkludgeは時間のかかる混乱になります。 –

+0

こんにちは、プロセスは簡単に繰り返す必要がありますか?たとえば、新しいバージョンのAPIがリリースされたときにスタブ実装を更新できるようにしたいとしますか? – OlduwanSteve

答えて

1

UMLモデリングツールは、選択した言語でデフォルト実装を生成することができます。一般に、ソースコード(Cヘッダを含む)のインポートもサポートされています。ヘッダーをインポートし、ソースコードを生成することができます。私は個人的にEnterprise Architectの経験があり、これらの操作の両方をサポートしています。

+0

ahはい、おそらくこれを行うでしょう(ただし、printステートメントではありません)。おそらく有料版でしかないのですが、私は何年もライセンスを取得していません。それをチェックします。ありがとう。 –

+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) 
関連する問題