如何用Doxygen v1.12.0自动生成C函数输入输出关系图?
实现思路与简便方案
1. 直接用Doxygen自带的Graphviz集成能力
这是最快的方式,不需要额外工具:
- 先在Doxygen配置里把
HAVE_DOT设为YES,DOT_PATH填好Graphviz的dot工具路径(确保已经装了Graphviz)。 - 在函数注释里直接嵌入DOT语法,用
@dot和@enddot包裹,比如:
/** * @brief 简单计算函数 * @param[in] mInput1 输入参数1 * @param[in] mInput2 输入参数2 * @param[out] mOutput1 输出结果 * @dot digraph calc_func_io { "mInput1" -> "calc_func"; "mInput2" -> "calc_func"; "calc_func" -> "mOutput1"; } * @enddot */ void calc_func(int mInput1, int mInput2, int* mOutput1) { *mOutput1 = mInput1 + mInput2; }
- 生成文档时,Doxygen会自动把这段DOT代码转成可点击的关系图,和函数参考信息绑定在一起。
2. 解析Doxygen的XML输出做批量生成
如果要给所有函数自动生成,不用手动写注释:
- 打开Doxygen配置的
GENERATE_XML=YES,让它生成包含所有函数、参数信息的XML文档。 - 写个简单脚本(Python、Perl都行),遍历XML里的函数节点:
- 提取函数名,再通过
@param[in]/@param[out]标记或者参数类型(指针大概率是输出)区分输入输出变量。 - 自动生成每个函数的DOT格式文本,然后调用Graphviz的
dot命令转成图片。
- 提取函数名,再通过
- 给个Python示例片段:
import xml.etree.ElementTree as ET import subprocess # 加载Doxygen生成的XML索引 tree = ET.parse('xml/index.xml') root = tree.getroot() for func in root.findall('.//memberdef[@kind="function"]'): func_name = func.find('name').text inputs = [] outputs = [] # 遍历每个参数 for param in func.findall('param'): param_name = param.find('declname').text # 从注释里找输入输出标记 param_desc = param.find('param').text if param.find('param') is not None else "" if '[out]' in param_desc or param.find('type').text.endswith('*'): outputs.append(param_name) else: inputs.append(param_name) # 生成DOT内容 dot_content = f'digraph {func_name}_io {{\n' for inp in inputs: dot_content += f' "{inp}" -> "{func_name}";\n' for outp in outputs: dot_content += f' "{func_name}" -> "{outp}";\n' dot_content += '}\n' # 保存DOT文件并生成图片 dot_file = f'{func_name}.dot' with open(dot_file, 'w') as f: f.write(dot_content) subprocess.run(['dot', '-Tpng', dot_file, '-o', f'{func_name}_io.png'])
3. 用Doxygen 1.12+的Lua脚本自动生成
Doxygen 1.12.0支持Lua脚本扩展,能在文档生成过程中自动处理:
- 写个Lua脚本,监听函数解析事件,自动提取输入输出参数,生成DOT代码插入到函数注释里:
function memberDefEnter(member) if member.kind ~= "function" then return end local dot_graph = "digraph " .. member.name .. "_io {\n" -- 遍历参数,根据方向生成边 for _, param in ipairs(member.params) do local param_name = param.declname if param.direction == "in" then dot_graph = dot_graph .. ' "' .. param_name .. '" -> "' .. member.name .. '";\n' elseif param.direction == "out" then dot_graph = dot_graph .. ' "' .. member.name .. '" -> "' .. param_name .. '";\n' end end dot_graph = dot_graph .. "}\n" -- 把DOT代码添加到函数的详细描述里 member.detailedDescription:addText("\n@dot\n" .. dot_graph .. "@enddot") end
- 在Doxygen配置里加
LUA_SCRIPT=your_script.lua,生成文档时就会自动给每个函数添加上输入输出关系图。
内容的提问来源于stack exchange,提问作者Mikael
相关产品推荐
相关产品推荐

