我想生成头文件中定义的过程的空实现。理想情况下,它们应该为指针返回 NULL,为整数返回 0,等等,并且在理想的情况下,还可以打印到 stderr 调用了哪个函数。
这样做的动机是需要实现一个包装器,将复杂的现有 API(头文件)的子集适应另一个库。 API中只有一小部分过程需要被委托,但具体是哪些过程并不清楚。所以我希望使用迭代方法,我运行这个自动生成的包装器,看看调用了什么,通过委托实现它,然后重复。
我已经看到从标头自动生成 C++ 文件?但答案似乎是 C++ 特定的。
那么,对于需要用简单的术语阐明问题的人来说,如何在给定头文件的情况下自动生成这样的实现?我更喜欢现有的工具 - 我目前对简单解决方案的最佳猜测是使用 pycparser。
更新谢谢大家。两个都很好的答案。还发布了我当前的黑客攻击。
所以,我将把 EA 建议标记为“答案”,因为我认为这可能是最好的想法。尽管我认为 cmock 建议在 TDD 方法中非常有效,其中库开发是由测试失败驱动的,但我最终可能会尝试这样做。但现在,我需要一种更快+更脏的方法,以交互方式工作(有问题的库是另一个交互式程序的动态加载插件,我正在尝试对 api 调用的顺序进行逆向工程......)
所以我最终做的是编写一个调用 pycparse 的 python 脚本。我将把它包含在这里,以防它对其他人有帮助,但它根本不通用(例如,假设所有函数都返回 int,并且有一个避免 typedef 内的 func def 的 hack)。
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)
UML 建模工具能够以所选语言生成默认实现。一般还支持导入源代码(包括C头文件)。您可以尝试导入标头并从中生成源代码。我个人有使用 Enterprise Architect 的经验,它支持这两种操作。
警告:这是一个未经研究的答案,因为我自己没有任何经验。
我认为您可能会幸运地使用专为单元测试而设计的模拟框架。这种框架的一个例子是:cmock
项目页面表明它将从标头生成代码。然后您可以获取代码并对其进行调整。