如何从C语言获取指向R控制台的FILE* 解决CRAN包提交stdout引用问题
解决方案
首先明确:R 没有公开导出的、可直接用于写入控制台的FILE*指针,R内部的输出相关文件指针属于未公开API,调用会违反CRAN规范,绝对不要使用。
以下是3种完全符合CRAN要求的处理方案,按推荐优先级排序:
方案1:从根源禁用Flex的输出逻辑(最推荐)
如果你仅使用Flex做词法解析,不需要用到它的默认输出能力,直接在Flex的.l规则文件头部添加如下配置,完全消除生成代码中对yyout、stdout的引用:
%option noyyoutput nodefault noinput nounput
生成的代码不会包含任何I/O操作相关的冗余逻辑,R CMD check的提示会直接消失,是CRAN审核最认可的处理方式。
方案2:替换Flex的输出宏对接R原生输出接口
如果你的场景确实需要Flex的输出能力,可直接自定义YY_OUTPUT宏,将Flex的输出逻辑替换为R的标准输出接口:
%{ #define YY_OUTPUT(buf, len) Rprintf("%.*s", (int)len, buf) %}
Flex生成代码时会自动用你定义的宏替代默认的fwrite到yyout的逻辑,所有输出直接走Rprintf,完全不会触碰stdout/FILE*相关逻辑。
方案3:用内存流承接Flex输出
如果因为特殊原因必须保留yyout相关逻辑,可以创建内存流承接Flex的输出,再统一转交给R的输出接口:
// 初始化内存流 char *buf = NULL; size_t buf_len = 0; FILE *mem_stream = open_memstream(&buf, &buf_len); // 修改Flex输出指针为内存流 yyout_set(mem_stream); // 运行Flex解析逻辑... // 解析完成后输出内容到R控制台 fflush(mem_stream); if (buf_len > 0) Rprintf("%.*s", (int)buf_len, buf); // 释放资源 fclose(mem_stream); free(buf);
Windows平台可使用兼容的_open_memstream接口,或者用跨平台的内存流实现,全程不会触碰系统标准输出/错误流,符合CRAN规范。
审核注意事项
处理完成后重新运行R CMD check,stdout引用的提示会消失。首次提交可在CRAN提交注释里简要说明你对Flex生成代码的I/O处理方案,审核员不会因此卡审。
内容的提问来源于stack exchange,提问作者seanmk
相关产品推荐
相关产品推荐

