从标头自动生成C代码

时间:2012-12-10 13:47:17

标签: c code-generation

我想生成头文件中定义的空过程。理想情况下,它们应该为指针返回NULL,为整数等返回0,并且在理想的世界中,还要向stderr打印调用哪个函数。

这样做的动机是需要实现一个包装器,它将复杂的现有API(头文件)的子集调整到另一个库。只需要委托API中的少量程序,但不清楚哪些程序。所以我希望使用一种迭代方法,在这种情况下,我针对这个自动生成的包装器运行,看看调用了什么,用委托来实现,然后重复。

我看到Automatically generate C++ file from header?,但答案似乎是C ++特定的。

因此,对于需要用简单术语拼写的问题的人来说,如何根据头文件自动生成这样的实现?我更喜欢现有的工具 - 我目前对一个简单解决方案的最佳猜测是使用pycparser。

更新谢谢大家。两个好的答案。还发布了我当前的黑客。

3 个答案:

答案 0 :(得分:2)

所以,我要将ea建议标记为“答案”,因为我认为这可能是最好的想法。虽然我认为cmock建议在tdd方法中可以很好地工作,其中库开发是由测试失败驱动的,我可能最终会尝试这样做。但是现在,我需要一种更快速+更脏的方法,以交互方式工作(所讨论的库是一个动态加载的插件,用于另一个交互式程序,我正在尝试对api调用的顺序进行反向工程......)

所以我最终做的是编写一个调用pycparse的python脚本。我会在这里包含它,以防它帮助其他人,但它根本不是一般的(假设所有函数都返回int,例如,并且有一个hack来避免在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)

答案 1 :(得分:1)

警告:这是一个未经研究的答案,因为我自己没有任何经验。

我认为你可能会对设计用于单元测试的模拟框架感到满意。这种框架的一个例子是:cmock

项目页面建议它将从标题生成代码。然后你可以拿出代码并进行调整。

答案 2 :(得分:1)

UML建模工具能够以所选语言生成默认实现。通常还支持导入源代码(包括C头)。您可以尝试导入标头并从中生成源代码。我个人有Enterprise Architect的经验,它支持这两种操作。