如何通过Python subprocess批量执行Cariad解析C文件得到的函数
Cariad工具批量执行函数实现方法
你之前写的脚本只能完成单次交互——写完指令就关标准输入流,工具进程直接跑完就退,没法连续发多条执行指令。按下面的方法改就能实现全流程自动批量跑:
核心实现逻辑
- 启动工具常驻进程后,先发
list-functions指令,从返回内容里提取所有合法函数名 - 全程保持子进程标准输入流开启,逐个拼接
execute <函数名>指令写入管道,每次写入后主动刷新缓冲区,避免指令卡在管道里发不出去 - 所有函数执行完成后,可按需发
dump-status打印变量状态、write-results <输出文件路径>导出CSV结果,最后发exit正常关闭工具进程
可直接运行的完整代码
import subprocess # 路径配置,和你之前手动用的路径保持一致即可 TOOL_PATH = r'C:\Users\drb\Desktop\Cariad_Tool\SFA_v0.9\bin\Signalflussanalyse.exe' C_FILE_PATH = r'C:\Users\drb\Desktop\Cariad_Tool\Source_PDK2_ISP_255\mainEHR.c' WORK_DIR = r'C:\Users\drb\Desktop\Cariad_Tool\Source_PDK2_ISP_255' RESULT_SAVE_PATH = r'C:\Users\drb\Desktop\Cariad_Tool\sfa_analysis_result.csv' # 启动交互子进程,用二进制模式读写规避Windows编码问题 proc = subprocess.Popen( [TOOL_PATH, C_FILE_PATH], cwd=WORK_DIR, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) # 第一步:发送list-functions指令,提取所有函数名 proc.stdin.write(b"list-functions\n") proc.stdin.flush() # 读输出直到解析完成标记出现 output_cache = b"" while b"Finished parsing all functions" not in output_cache: output_cache += proc.stdout.readline() # 跳过中间的德语帮助文本,收集末尾的纯函数名列表 func_list = [] while True: line = proc.stdout.readline().decode("utf-8").strip() # 读到空行且已经收集到函数,说明函数列表段结束 if not line and len(func_list) > 0: break # 过滤掉帮助文本里的内置指令行,只留实际C函数名 builtin_cmds = {"list-functions", "execute <function-name>", "cyclic-execute <function-name>", "write-results <file-name>", "dump-status", "reset", "exit"} if line and not line.startswith(" ") and not line.endswith(":") and line not in builtin_cmds: func_list.append(line) print(f"共提取到{len(func_list)}个待分析函数") # 第二步:批量执行所有函数 for func in func_list: print(f"正在分析函数: {func}") # 遇到需要循环执行的函数(比如Stateflow逻辑),把execute替换成cyclic-execute即可 exec_cmd = f"execute {func}\n".encode("utf-8") proc.stdin.write(exec_cmd) proc.stdin.flush() # 等待当前函数执行完成,避免指令堆积 while True: ret = proc.stdout.readline() if b"[INFO]" in ret or b"error" in ret.lower(): break # 可选:如果怕函数之间状态干扰,每次执行完发reset重置所有变量状态 # proc.stdin.write(b"reset\n") # proc.stdin.flush() # 第三步:导出结果、打印状态,退出工具 proc.stdin.write(f"write-results {RESULT_SAVE_PATH}\n".encode("utf-8")) proc.stdin.write(b"dump-status\n") proc.stdin.write(b"exit\n") proc.stdin.flush() # 读取剩余所有输出,把dump-status的内容存本地 final_output = b"" while proc.poll() is None: final_output += proc.stdout.read() proc.wait() with open("dump_status.txt", "wb") as f: f.write(final_output) print(f"全部分析完成,结果已保存到: {RESULT_SAVE_PATH}")
注意事项
- 所有写入管道的指令必须加
\n结尾,和手动敲命令行按回车的效果一致,写完必须调用flush(),否则指令会卡在缓冲区不会被工具接收 - 所有指令发完之前不要调用
stdin.close(),否则工具会提前收到结束信号直接退出 - 二进制读写模式可以自动规避德语特殊字符、Windows控制台编码不一致导致的乱码报错
内容的提问来源于stack exchange,提问作者drashti bhatt
相关产品推荐
相关产品推荐

