【ARM】重新定义低级库函数,以便能够直接使用 C 库中的高级库函数
Redefining low-level library functions to enable direct use of high-level library functions in the C library
If you define your own version of __FILE
, your own fputc()
and ferror()
functions, and the __stdout
object, you can use all of the printf()
family, fwrite()
, fputs()
, puts() and
the C++ object std::cout
unchanged from the library.
These examples show you how to do this. However, consider modifying the system I/O functions instead of these low-level library functions if you require real file handling.
You are not required to re-implement every function shown in these examples. Only re-implement the functions that are used in your application.
Retargeting printf()
#include <stdio.h> struct __FILE { int handle; /* Whatever you require here. If the only file you are using is */ /* standard output using printf() for debugging, no file handling */ /* is required. */ }; /* FILE is typedef'd in stdio.h. */ FILE __stdout; int fputc(int ch, FILE *f) { /* Your implementation of fputc(). */ return ch; } int ferror(FILE *f) { /* Your implementation of ferror(). */ return 0; } void test(void) { printf("Hello world\n"); }
Note
Be aware of endianness with
fputc()
.fputc()
takes anint
parameter, but contains only a character. Whether the character is in the first or the last byte of the integer variable depends on the endianness. The following code sample avoids problems with endianness:
extern void sendchar(char *ch); int fputc(int ch, FILE *f) { /* example: write a character to an LCD */ char tempch = ch; // temp char avoids endianness issue sendchar(&tempch); // sendchar(&ch) would not work everywhere return ch; }
Retargeting cout
File 1: Re-implement any functions that require re-implementation.
#include <stdio.h> namespace std { struct __FILE { int handle; /* Whatever you require here. If the only file you are using is */ /* standard output using printf() for debugging, no file handling */ /* is required. */ }; FILE __stdout; FILE __stdin; FILE __stderr; int fgetc(FILE *f) { /* Your implementation of fgetc(). */ return 0; } int fputc(int c, FILE *stream) { /* Your implementation of fputc(). */ } int ferror(FILE *stream) { /* Your implementation of ferror(). */ } long int ftell(FILE *stream) { /* Your implementation of ftell(). */ } int fclose(FILE *f) { /* Your implementation of fclose(). */ return 0; } int fseek(FILE *f, long nPos, int nMode) { /* Your implementation of fseek(). */ return 0; } int fflush(FILE *f) { /* Your implementation of fflush(). */ return 0; } }
File 2: Print "Hello world" using your re-implemented functions.
#include <stdio.h> #include <iostream> using namespace std; int main() { cout << "Hello world\n"; return 0; }
By default, fread()
and fwrite()
call fast block input/output functions that are part of the Arm® stream implementation. If you define your own __FILE
structure instead of using the Arm stream implementation, fread()
and fwrite()
call fgetc()
instead of calling the block input/output functions.
【来源】
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
2019-01-15 【rt-thread】线程内置定时器的作用--
2019-01-15 【rt-thread】软件定时器组件超时界限的一点理解
2018-01-15 KEIL打开的工程所在目录过深将会编译出错
2018-01-15 【rt-thread】 learning notes