*.h文件头部常用 #ifndef _STDIO_H_,#if __cplusplus

本文深入探讨了C++编程中头文件的#ifndef和externC的关键概念及应用,包括如何解决声明冲突、函数在C++和C++之间的调用问题,以及如何在不同编译环境下正确使用externC来避免链接失败。通过实例分析,详细解释了头文件中的#ifndef和externC的具体用法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

头件的中的#ifndef,这是一个很关键的东西。比如你有两个C文件,这两个C文件都include了同一个头文件。而编译时,这两个C文件要一同编译成一个可运行文件,于是问题来了,大量的声明冲突。 

 

还是把头文件的内容都放在#ifndef和#endif中吧。不管你的头文件会不会被多个文件引用,你都要加上这个。一般格式是这样的:

#ifndef <标识>
#define <标识>

......

#endif

<标识>在理论上来说可以是自由命名的,但每个头文件的这个“标识”都应该是唯一的。标识的命名规则一般是头文件名全大写,前后加下划线,并把文件名中的“.”也变成下划线,如:stdio.h

#ifndef _STDIO_H_
#define _STDIO_H_

......

#endif

 

extern “C”

  在C++环境下使用C函数的时候,常常会出现编译器无法找到obj模块中的C函数定义,从而导致链接失败的情况,应该如何解决这种情况呢?C++语言在编译的时候为了解决函数的多态问题,会将函数名和参数联合起来生成一个中间的函数名称,而C语言则不会,因此会造成链接时找不到对应函数的情况,此时C函数就需要用extern “C”进行链接指定,这告诉编译器,请保持我的名称,不要给我生成用于链接的中间函数名。

  下面是一个标准的写法:

//在.h文件的头上
#if __cplusplus
extern "C"{
#endif

 

//.h文件结束的地方
#if __cplusplus
}
#endif  

 

由于C++编译器需要支持函数的重载,会改变函数的名称,因此dll的导出函数通常是标准C定义的。这就使得C和C++的互相调用变得很常见。但是有时可能又会直接用C来调用,不想重新写代码,让标准C编写的dll函数定义在C和C++编译器下都能编译通过,通常会使用以下的格式:(这个格式在很多成熟的代码中很常见)
#if defined(__cplusplus)
extern "C" {
#endif
// 在这里写标准C程序,例如dll导出函数的定义
#ifdef __cplusplus
      }
#endif


下面解释一下上面的代码:
首先__cplusplus是C++编译器内部定义的宏,如果使用的C编译器,__cplusplus宏不会被定义。它可以作为区分使用的是C编译器还是C++编译器的标志。在标准C中C代码直接写就可以了。而在C++中,需要加extern "C"或包含在extern "C"块中。由于标准C是不支持extern "C"的,会产生变异错误,所以使用预编译指令通过__cplusplus来判断只有在使用C++编译器的时候才定义extern "C"。
文章出处:飞诺网(http://www.diybl.com/course/3_program/c++/cppjs/20090517/167150.html)

 

1. 与extern对应的关键字是static,被它修饰的全局变量和函数只能在本模块中使用。
常常见extern放在函数的前面成为函数声明的一部分,那么,C语言的关键字extern在函数的声明中起什么作用?

  答案与分析:
  如果函数的声明中带有关键字extern,仅仅是暗示这个函数可能在别的源文件里定义,没有其它作用。即下述两个函数声明没有明显的区别:
  extern int f(); 和int f();
  当然,这样的用处还是有的,就是在程序中取代include “*.h”来声明函数,在一些复杂的项目中,我比较习惯在所有的函数声明前添加extern修饰。

4 问题:extern 函数

  当函数提供方单方面修改函数原型时,如果使用方不知情,继续沿用原来的extern申明,这样编译时编译器不会报错。但是在运行过程中,因为少了或者多了输入参数,
往往会造成系统错误,这种情况应该如何解决?
  答案与分析:
  目前业界针对这种情况的处理没有一个很完美的方案,通常的做法是提供方在自己的xxx_pub.h中提供对外部接口的声明,然后调用方include该头文件,从而省去
extern这一步。以避免这种错误。

在一个头文件中声明的函数
//head.h
#ifndef __HEAD_H__
#define __HEAD_H__
extern void fun();
#endif
的作用是想让其他有 #include "head.h"的文件都有 extern void fun();
在连接的时候就会自动去找到fun函数的实现。因为对于函数来说void fun();这样也算是声明。所以我认为这里写不写extern都可以。

但是如果是变量就不同了。
//head.h
#ifndef __HEAD_H__
#define __HEAD_H__
extern int i;
#endif

//test.cpp
#include "head.h"
int i=3;

//main.cpp
#include "head.h"
#include <iostream>
using namespace std;
//如果head.h里面没有写 extern int i;在这里添加也一样
//extern int i;
int main()
{
       cout<<i<<endl;
       return 0;
}

extern可以置于变量或者函数前,以表示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。

2 问题:extern 变量

在一个源文件里定义了一个数组: char a[6];   
在另外一个文件里用下列语句进行了声明: extern char *a;
  请问,这样可以吗?
  答案与分析:
  1)、不可以,程序运行时会告诉你非法访问。原因在于,指向类型T的指针并不等价于类型T的数组。extern char *a声明的是一个指针变量而不是字符数组,
因此与实际的定义不同,从而造成运行时非法访问。应该将声明改为extern char a[ ]。
  2)、例子分析如下,如果a[] = "abcd",则外部变量a=0x61626364 (abcd的ASCII码值),*a显然没有意义,显然a指向的空间(0x61626364)没有意义,易出现非法内存访问。
  3)、这提示我们,在使用extern时候要严格对应声明时的格式,在实际编程中,这样的错误屡见不鲜。
  4)、extern用在变量声明中常常有这样一个作用,你在*.c文件中声明了一个全局的变量,这个全局的变量如果要被引用,就放在*.h中并用extern来声明。

http://blog.sina.com.cn/s/blog_4ed9fbab01014exl.html

#include "stm32f10x.h" // Device header #include "Delay.h" #include "Key.h" #include "Led.h" #include "serial.h" #include "OLED.h" #include "Time.h" #include "Stack.h" static unsigned char Clear_Index=0; //清零检索 static unsigned char Count_Index=0; //计算检索 static uint32_t Index=0; static unsigned char Firmula[100]; //存储算数式子 static unsigned int Result; //存储结果 void USART1_IRQHandler(void); unsigned char a=19; int main(void) { Key_Init(); OLED_Init(); Serial_Init(); while(1) { if(Key_GetNum1()) //计算算数式 { Result=Deposit(Firmula); Count_Index=1; } if(Count_Index) //发送结果 { if(Key_GetNum2()) { printf("结果=%d",Result); OLED_ShowNum(1,1,Result,4); Index=0; Clear_Index=1; Count_Index=0; } } if(Clear_Index) //清零 { if(Key_GetNum3()) { Clear_Index=0; Init(); } } else if(!Clear_Index) { if(Key_GetNum3()) { printf("请输入运算式"); } } } } void USART1_IRQHandler(void) //串口中断函数 { Firmula[Index]=Serial_Getbyte(); printf("%c",Firmula[Index]); Index++; }#include "stm32f10x.h"// Device header #include "Stack.h" #include<ctype.h> #include "Serial.h" Stack_char Stack_CHAR; Stack_num Stack_NUM; uint8_t Push_char(Stack_char *stack,uint8_t CH); uint8_t Pop_char(Stack_char *stack,uint8_t *c); uint8_t Push_num(Stack_num *stack,unsigned int NUM); uint8_t Pop_num(Stack_num *stack,unsigned int *n); void Eval(void); uint16_t Priority(uint8_t ch); void Init(void) { Stack_NUM.top=0; Stack_CHAR.top=0; } uint16_t Priority(uint8_t ch) { switch(ch) { case '(' : case ')' : return 3; case '*' : case '/' : return 2; case '+' : case '-' : return 1; default : return 0; //分化优先级 } } uint32_t Deposit(uint8_t *String) { unsigned int i,j,index=0; uint8_t C; Init(); for(i = 0;String[i]!='\0'&&i < Stack_Size ;i++) { if(isdigit(String[i])) //判断是否 '0'<=string<='9' { index=0; j=i; for(;isdigit(String[j])&&j< Stack_Size;j++) { index=index*10+(String[j]-'0'); } Push_num(&Stack_NUM,index); i=j-1; //因为for循环多加了1,所以减去1 } else if(String[i]=='(') { Push_char(&Stack_CHAR,String[i]); } else if(String[i]==')') { while(Stack_CHAR.ch[Stack_CHAR.top] != '(') {Eval();} //直到遇到左括号,并且计算 if(Stack_CHAR.top != 0 && Stack_CHAR.ch[Stack_CHAR.top] == '(') { Pop_char(&Stack_CHAR,&C); //弹出左括号 } } else { while(Stack_CHAR.top!=0&&Stack_CHAR.ch[Stack_CHAR.top]!='('&&Priority(Stack_CHAR.ch[Stack_CHAR.top])>=Priority(String[i])) { Eval(); } Push_char(&Stack_CHAR,String[i]); } } while(Stack_CHAR.top) { Eval(); } //循环直至操作符为空 return Stack_NUM.num[Stack_NUM.top]; //此时数栈顶元素即为表达式值 } void Eval(void) { uint32_t a,x,b; uint8_t cha; Pop_num(&Stack_NUM,&b); Pop_num(&Stack_NUM,&a); //由于栈是陷进后出,与队列有区别(先进出) Pop_char(&Stack_CHAR,&cha); switch(cha) { case '*' : x=a*b;break; //计算 case '/' : { if(b==0) {printf("除数不能为0");x=0;} else {x=a/b;} break; } case '+' : {x=a+b;break;} case '-' : {x=a-b;break;} default :break; } Push_num(&Stack_NUM,x); } uint8_t Push_char(Stack_char *stack,uint8_t CH) { if(stack->top>=Stack_Size) { return 0; } stack->top++; stack->ch[stack->top]=CH; return 1; } uint8_t Push_num(Stack_num *stack,unsigned int NUM) { if(stack->top>=Stack_Size) { return 0; } stack->top++; stack->num[stack->top]=NUM; return 1; } uint8_t Pop_char(Stack_char *stack,uint8_t *c) { if(stack->top<=0) { return 0; } *c=stack->ch[stack->top]; stack->top--; return 1; } uint8_t Pop_num(Stack_num *stack,unsigned int *n) { if(stack->top<=0) { return 0; } *n=stack->num[stack->top]; stack->top--; return 1; } /* Copyright (C) ARM Ltd., 1999,2014 */ /* All rights reserved */ /* * RCS $Revision$ * Checkin $Date$ * Revising $Author: agrant $ */ #ifndef __stdint_h #define __stdint_h #define __ARMCLIB_VERSION 5060034 #ifdef __INT64_TYPE__ /* armclang predefines '__INT64_TYPE__' and '__INT64_C_SUFFIX__' */ #define __INT64 __INT64_TYPE__ #else /* armcc has builtin '__int64' which can be used in --strict mode */ #define __INT64 __int64 #define __INT64_C_SUFFIX__ ll #endif #define __PASTE2(x, y) x ## y #define __PASTE(x, y) __PASTE2(x, y) #define __INT64_C(x) __ESCAPE__(__PASTE(x, __INT64_C_SUFFIX__)) #define __UINT64_C(x) __ESCAPE__(__PASTE(x ## u, __INT64_C_SUFFIX__)) #if defined(__clang__) || (defined(__ARMCC_VERSION) && !defined(__STRICT_ANSI__)) /* armclang and non-strict armcc allow 'long long' in system headers */ #define __LONGLONG long long #else /* strict armcc has '__int64' */ #define __LONGLONG __int64 #endif #ifndef __STDINT_DECLS #define __STDINT_DECLS #undef __CLIBNS #ifdef __cplusplus namespace std { #define __CLIBNS std:: extern "C" { #else #define __CLIBNS #endif /* __cplusplus */ /* * 'signed' is redundant below, except for 'signed char' and if * the typedef is used to declare a bitfield. */ /* 7.18.1.1 */ /* exact-width signed integer types */ typedef signed char int8_t; typedef signed short int int16_t; typedef signed int int32_t; typedef signed __INT64 int64_t; /* exact-width unsigned integer types */ typedef unsigned char uint8_t; typedef unsigned short int uint16_t; typedef unsigned int uint32_t; typedef unsigned __INT64 uint64_t; /* 7.18.1.2 */ /* smallest type of at least n bits */ /* minimum-width signed integer types */ typedef signed char int_least8_t; typedef signed short int int_least16_t; typedef signed int int_least32_t; typedef signed __INT64 int_least64_t; /* minimum-width unsigned integer types */ typedef unsigned char uint_least8_t; typedef unsigned short int uint_least16_t; typedef unsigned int uint_least32_t; typedef unsigned __INT64 uint_least64_t; /* 7.18.1.3 */ /* fastest minimum-width signed integer types */ typedef signed int int_fast8_t; typedef signed int int_fast16_t; typedef signed int int_fast32_t; typedef signed __INT64 int_fast64_t; /* fastest minimum-width unsigned integer types */ typedef unsigned int uint_fast8_t; typedef unsigned int uint_fast16_t; typedef unsigned int uint_fast32_t; typedef unsigned __INT64 uint_fast64_t; /* 7.18.1.4 integer types capable of holding object pointers */ #if __sizeof_ptr == 8 typedef signed __INT64 intptr_t; typedef unsigned __INT64 uintptr_t; #else typedef signed int intptr_t; typedef unsigned int uintptr_t; #endif /* 7.18.1.5 greatest-width integer types */ typedef signed __LONGLONG intmax_t; typedef unsigned __LONGLONG uintmax_t; #if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) /* 7.18.2.1 */ /* minimum values of exact-width signed integer types */ #define INT8_MIN -128 #define INT16_MIN -32768 #define INT32_MIN (~0x7fffffff) /* -2147483648 is unsigned */ #define INT64_MIN __INT64_C(~0x7fffffffffffffff) /* -9223372036854775808 is unsigned */ /* maximum values of exact-width signed integer types */ #define INT8_MAX 127 #define INT16_MAX 32767 #define INT32_MAX 2147483647 #define INT64_MAX __INT64_C(9223372036854775807) /* maximum values of exact-width unsigned integer types */ #define UINT8_MAX 255 #define UINT16_MAX 65535 #define UINT32_MAX 4294967295u #define UINT64_MAX __UINT64_C(18446744073709551615) /* 7.18.2.2 */ /* minimum values of minimum-width signed integer types */ #define INT_LEAST8_MIN -128 #define INT_LEAST16_MIN -32768 #define INT_LEAST32_MIN (~0x7fffffff) #define INT_LEAST64_MIN __INT64_C(~0x7fffffffffffffff) /* maximum values of minimum-width signed integer types */ #define INT_LEAST8_MAX 127 #define INT_LEAST16_MAX 32767 #define INT_LEAST32_MAX 2147483647 #define INT_LEAST64_MAX __INT64_C(9223372036854775807) /* maximum values of minimum-width unsigned integer types */ #define UINT_LEAST8_MAX 255 #define UINT_LEAST16_MAX 65535 #define UINT_LEAST32_MAX 4294967295u #define UINT_LEAST64_MAX __UINT64_C(18446744073709551615) /* 7.18.2.3 */ /* minimum values of fastest minimum-width signed integer types */ #define INT_FAST8_MIN (~0x7fffffff) #define INT_FAST16_MIN (~0x7fffffff) #define INT_FAST32_MIN (~0x7fffffff) #define INT_FAST64_MIN __INT64_C(~0x7fffffffffffffff) /* maximum values of fastest minimum-width signed integer types */ #define INT_FAST8_MAX 2147483647 #define INT_FAST16_MAX 2147483647 #define INT_FAST32_MAX 2147483647 #define INT_FAST64_MAX __INT64_C(9223372036854775807) /* maximum values of fastest minimum-width unsigned integer types */ #define UINT_FAST8_MAX 4294967295u #define UINT_FAST16_MAX 4294967295u #define UINT_FAST32_MAX 4294967295u #define UINT_FAST64_MAX __UINT64_C(18446744073709551615) /* 7.18.2.4 */ /* minimum value of pointer-holding signed integer type */ #if __sizeof_ptr == 8 #define INTPTR_MIN INT64_MIN #else #define INTPTR_MIN INT32_MIN #endif /* maximum value of pointer-holding signed integer type */ #if __sizeof_ptr == 8 #define INTPTR_MAX INT64_MAX #else #define INTPTR_MAX INT32_MAX #endif /* maximum value of pointer-holding unsigned integer type */ #if __sizeof_ptr == 8 #define UINTPTR_MAX UINT64_MAX #else #define UINTPTR_MAX UINT32_MAX #endif /* 7.18.2.5 */ /* minimum value of greatest-width signed integer type */ #define INTMAX_MIN __ESCAPE__(~0x7fffffffffffffffll) /* maximum value of greatest-width signed integer type */ #define INTMAX_MAX __ESCAPE__(9223372036854775807ll) /* maximum value of greatest-width unsigned integer type */ #define UINTMAX_MAX __ESCAPE__(18446744073709551615ull) /* 7.18.3 */ /* limits of ptrdiff_t */ #if __sizeof_ptr == 8 #define PTRDIFF_MIN INT64_MIN #define PTRDIFF_MAX INT64_MAX #else #define PTRDIFF_MIN INT32_MIN #define PTRDIFF_MAX INT32_MAX #endif /* limits of sig_atomic_t */ #define SIG_ATOMIC_MIN (~0x7fffffff) #define SIG_ATOMIC_MAX 2147483647 /* limit of size_t */ #if __sizeof_ptr == 8 #define SIZE_MAX UINT64_MAX #else #define SIZE_MAX UINT32_MAX #endif /* limits of wchar_t */ /* NB we have to undef and redef because they're defined in both * stdint.h and wchar.h */ #undef WCHAR_MIN #undef WCHAR_MAX #if defined(__WCHAR32) || (defined(__ARM_SIZEOF_WCHAR_T) && __ARM_SIZEOF_WCHAR_T == 4) #define WCHAR_MIN 0 #define WCHAR_MAX 0xffffffffU #else #define WCHAR_MIN 0 #define WCHAR_MAX 65535 #endif /* limits of wint_t */ #define WINT_MIN (~0x7fffffff) #define WINT_MAX 2147483647 #endif /* __STDC_LIMIT_MACROS */ #if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) /* 7.18.4.1 macros for minimum-width integer constants */ #define INT8_C(x) (x) #define INT16_C(x) (x) #define INT32_C(x) (x) #define INT64_C(x) __INT64_C(x) #define UINT8_C(x) (x ## u) #define UINT16_C(x) (x ## u) #define UINT32_C(x) (x ## u) #define UINT64_C(x) __UINT64_C(x) /* 7.18.4.2 macros for greatest-width integer constants */ #define INTMAX_C(x) __ESCAPE__(x ## ll) #define UINTMAX_C(x) __ESCAPE__(x ## ull) #endif /* __STDC_CONSTANT_MACROS */ #ifdef __cplusplus } /* extern "C" */ } /* namespace std */ #endif /* __cplusplus */ #endif /* __STDINT_DECLS */ #ifdef __cplusplus #ifndef __STDINT_NO_EXPORTS using ::std::int8_t; using ::std::int16_t; using ::std::int32_t; using ::std::int64_t; using ::std::uint8_t; using ::std::uint16_t; using ::std::uint32_t; using ::std::uint64_t; using ::std::int_least8_t; using ::std::int_least16_t; using ::std::int_least32_t; using ::std::int_least64_t; using ::std::uint_least8_t; using ::std::uint_least16_t; using ::std::uint_least32_t; using ::std::uint_least64_t; using ::std::int_fast8_t; using ::std::int_fast16_t; using ::std::int_fast32_t; using ::std::int_fast64_t; using ::std::uint_fast8_t; using ::std::uint_fast16_t; using ::std::uint_fast32_t; using ::std::uint_fast64_t; using ::std::intptr_t; using ::std::uintptr_t; using ::std::intmax_t; using ::std::uintmax_t; #endif #endif /* __cplusplus */ #undef __INT64 #undef __LONGLONG #endif /* __stdint_h */ /* end of stdint.h */ 在不改变原代码变量名情况下,实现小数点预算
最新发布
07-16
/*---------------------------------------------------------------------------/ / FatFs - FAT file system module include file R0.09 (C)ChaN, 2011 /----------------------------------------------------------------------------/ / FatFs module is a generic FAT file system module for small embedded systems. / This is a free software that opened for education, research and commercial / developments under license policy of following trems. / / Copyright (C) 2011, ChaN, all right reserved. / / * The FatFs module is a free software and there is NO WARRANTY. / * No restriction on use. You can use, modify and redistribute it for / personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY. / * Redistributions of source code must retain the above copyright notice. / /----------------------------------------------------------------------------*/ #ifndef _FATFS #define _FATFS 6502 /* Revision ID */ #ifdef __cplusplus extern "C" { #endif #include "integer.h" /* Basic integer types */ #include "ffconf.h" /* FatFs configuration options */ #include "HeaderFiles.h" #if _FATFS != _FFCONF #error Wrong configuration file (ffconf.h). #endif /* Definitions of volume management */ #if _MULTI_PARTITION /* Multiple partition configuration */ typedef struct { BYTE pd; /* Physical drive number */ BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */ } PARTITION; extern PARTITION VolToPart[]; /* Volume - Partition resolution table */ #define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive number */ #define LD2PT(vol) (VolToPart[vol].pt) /* Get partition index */ #else /* Single partition configuration */ #define LD2PD(vol) (vol) /* Each logical drive is bound to the same physical drive number */ #define LD2PT(vol) 0 /* Always mounts the 1st partition or in SFD */ #endif /* Type of path name strings on FatFs API */ #if _LFN_UNICODE /* Unicode string */ #if !_USE_LFN #error _LFN_UNICODE must be 0 in non-LFN cfg. #endif #ifndef _INC_TCHAR typedef WCHAR TCHAR; #define _T(x) L ## x #define _TEXT(x) L ## x #endif #else /* ANSI/OEM string */ #ifndef _INC_TCHAR typedef char TCHAR; #define _T(x) x #define _TEXT(x) x #endif #endif /* File system object structure (FATFS) */ typedef struct { BYTE fs_type; /* FAT sub-type (0:Not mounted) */ BYTE drv; /* Physical drive number */ BYTE csize; /* Sectors per cluster (1,2,4...128) */ BYTE n_fats; /* Number of FAT copies (1,2) */ BYTE wflag; /* win[] dirty flag (1:must be written back) */ BYTE fsi_flag; /* fsinfo dirty flag (1:must be written back) */ WORD id; /* File system mount ID */ WORD n_rootdir; /* Number of root directory entries (FAT12/16) */ #if _MAX_SS != 512 WORD ssize; /* Bytes per sector (512, 1024, 2048 or 4096) */ #endif #if _FS_REENTRANT _SYNC_t sobj; /* Identifier of sync object */ #endif #if !_FS_READONLY DWORD last_clust; /* Last allocated cluster */ DWORD free_clust; /* Number of free clusters */ DWORD fsi_sector; /* fsinfo sector (FAT32) */ #endif #if _FS_RPATH DWORD cdir; /* Current directory start cluster (0:root) */ #endif DWORD n_fatent; /* Number of FAT entries (= number of clusters + 2) */ DWORD fsize; /* Sectors per FAT */ DWORD fatbase; /* FAT start sector */ DWORD dirbase; /* Root directory start sector (FAT32:Cluster#) */ DWORD database; /* Data start sector */ DWORD winsect; /* Current sector appearing in the win[] */ BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and Data on tiny cfg) */ } FATFS; /* File object structure (FIL) */ typedef struct { FATFS* fs; /* Pointer to the owner file system object */ WORD id; /* Owner file system mount ID */ BYTE flag; /* File status flags */ BYTE pad1; DWORD fptr; /* File read/write pointer (0 on file open) */ DWORD fsize; /* File size */ DWORD sclust; /* File start cluster (0 when fsize==0) */ DWORD clust; /* Current cluster */ DWORD dsect; /* Current data sector */ #if !_FS_READONLY DWORD dir_sect; /* Sector containing the directory entry */ BYTE* dir_ptr; /* Ponter to the directory entry in the window */ #endif #if _USE_FASTSEEK DWORD* cltbl; /* Pointer to the cluster link map table (null on file open) */ #endif #if _FS_SHARE UINT lockid; /* File lock ID (index of file semaphore table) */ #endif #if !_FS_TINY BYTE buf[_MAX_SS]; /* File data read/write buffer */ #endif } FIL; /* Directory object structure (DIR) */ typedef struct { FATFS* fs; /* Pointer to the owner file system object */ WORD id; /* Owner file system mount ID */ WORD index; /* Current read/write index number */ DWORD sclust; /* Table start cluster (0:Root dir) */ DWORD clust; /* Current cluster */ DWORD sect; /* Current sector */ BYTE* dir; /* Pointer to the current SFN entry in the win[] */ BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */ #if _USE_LFN WCHAR* lfn; /* Pointer to the LFN working buffer */ WORD lfn_idx; /* Last matched LFN index number (0xFFFF:No LFN) */ #endif } DIR; /* File status structure (FILINFO) */ typedef struct { DWORD fsize; /* File size */ WORD fdate; /* Last modified date */ WORD ftime; /* Last modified time */ BYTE fattrib; /* Attribute */ TCHAR fname[13]; /* Short file name (8.3 format) */ #if _USE_LFN TCHAR* lfname; /* Pointer to the LFN buffer */ UINT lfsize; /* Size of LFN buffer in TCHAR */ #endif } FILINFO; /* File function return code (FRESULT) */ typedef enum { FR_OK = 0, /* (0) Succeeded */ FR_DISK_ERR, /* (1) A hard error occured in the low level disk I/O layer */ FR_INT_ERR, /* (2) Assertion failed */ FR_NOT_READY, /* (3) The physical drive cannot work */ FR_NO_FILE, /* (4) Could not find the file */ FR_NO_PATH, /* (5) Could not find the path */ FR_INVALID_NAME, /* (6) The path name format is invalid */ FR_DENIED, /* (7) Acces denied due to prohibited access or directory full */ FR_EXIST, /* (8) Acces denied due to prohibited access */ FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */ FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */ FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */ FR_NOT_ENABLED, /* (12) The volume has no work area */ FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */ FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any parameter error */ FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */ FR_LOCKED, /* (16) The operation is rejected according to the file shareing policy */ FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */ FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > _FS_SHARE */ FR_INVALID_PARAMETER /* (19) Given parameter is invalid */ } FRESULT; /*--------------------------------------------------------------*/ /* FatFs module application interface */ FRESULT f_mount (BYTE, FATFS*); /* Mount/Unmount a logical drive */ FRESULT f_open (FIL*, const TCHAR*, BYTE); /* Open or create a file */ FRESULT f_read (FIL*, void*, UINT, UINT*); /* Read data from a file */ FRESULT f_lseek (FIL*, DWORD); /* Move file pointer of a file object */ FRESULT f_close (FIL*); /* Close an open file object */ FRESULT f_opendir (DIR*, const TCHAR*); /* Open an existing directory */ FRESULT f_readdir (DIR*, FILINFO*); /* Read a directory item */ FRESULT f_stat (const TCHAR*, FILINFO*); /* Get file status */ FRESULT f_write (FIL*, const void*, UINT, UINT*); /* Write data to a file */ FRESULT f_getfree (const TCHAR*, DWORD*, FATFS**); /* Get number of free clusters on the drive */ FRESULT f_truncate (FIL*); /* Truncate file */ FRESULT f_sync (FIL*); /* Flush cached data of a writing file */ FRESULT f_unlink (const TCHAR*); /* Delete an existing file or directory */ FRESULT f_mkdir (const TCHAR*); /* Create a new directory */ FRESULT f_chmod (const TCHAR*, BYTE, BYTE); /* Change attriburte of the file/dir */ FRESULT f_utime (const TCHAR*, const FILINFO*); /* Change timestamp of the file/dir */ FRESULT f_rename (const TCHAR*, const TCHAR*); /* Rename/Move a file or directory */ FRESULT f_chdrive (BYTE); /* Change current drive */ FRESULT f_chdir (const TCHAR*); /* Change current directory */ FRESULT f_getcwd (TCHAR*, UINT); /* Get current directory */ FRESULT f_forward (FIL*, UINT(*)(const BYTE*,UINT), UINT, UINT*); /* Forward data to the stream */ FRESULT f_mkfs (BYTE, BYTE, UINT); /* Create a file system on the drive */ FRESULT f_fdisk (BYTE, const DWORD[], void*); /* Divide a physical drive into some partitions */ int f_putc (TCHAR, FIL*); /* Put a character to the file */ int f_puts (const TCHAR*, FIL*); /* Put a string to the file */ int f_printf (FIL*, const TCHAR*, ...); /* Put a formatted string to the file */ TCHAR* f_gets (TCHAR*, int, FIL*); /* Get a string from the file */ #define f_eof(fp) (((fp)->fptr == (fp)->fsize) ? 1 : 0) #define f_error(fp) (((fp)->flag & FA__ERROR) ? 1 : 0) #define f_tell(fp) ((fp)->fptr) #define f_size(fp) ((fp)->fsize) #ifndef EOF #define EOF (-1) #endif /*--------------------------------------------------------------*/ /* Additional user defined functions */ /* RTC function */ #if !_FS_READONLY DWORD get_fattime (void); #endif /* Unicode support functions */ #if _USE_LFN /* Unicode - OEM code conversion */ WCHAR ff_convert (WCHAR, UINT); /* OEM-Unicode bidirectional conversion */ WCHAR ff_wtoupper (WCHAR); /* Unicode upper-case conversion */ #if _USE_LFN == 3 /* Memory functions */ void* ff_memalloc (UINT); /* Allocate memory block */ void ff_memfree (void*); /* Free memory block */ #endif #endif /* Sync functions */ #if _FS_REENTRANT int ff_cre_syncobj (BYTE, _SYNC_t*);/* Create a sync object */ int ff_req_grant (_SYNC_t); /* Lock sync object */ void ff_rel_grant (_SYNC_t); /* Unlock sync object */ int ff_del_syncobj (_SYNC_t); /* Delete a sync object */ #endif /*--------------------------------------------------------------*/ /* Flags and offset address */ /* File access control and file status flags (FIL.flag) */ #define FA_READ 0x01 #define FA_OPEN_EXISTING 0x00 #define FA__ERROR 0x80 #if !_FS_READONLY #define FA_WRITE 0x02 #define FA_CREATE_NEW 0x04 #define FA_CREATE_ALWAYS 0x08 #define FA_OPEN_ALWAYS 0x10 #define FA__WRITTEN 0x20 #define FA__DIRTY 0x40 #endif /* FAT sub type (FATFS.fs_type) */ #define FS_FAT12 1 #define FS_FAT16 2 #define FS_FAT32 3 /* File attribute bits for directory entry */ #define AM_RDO 0x01 /* Read only */ #define AM_HID 0x02 /* Hidden */ #define AM_SYS 0x04 /* System */ #define AM_VOL 0x08 /* Volume label */ #define AM_LFN 0x0F /* LFN entry */ #define AM_DIR 0x10 /* Directory */ #define AM_ARC 0x20 /* Archive */ #define AM_MASK 0x3F /* Mask of defined bits */ /* Fast seek feature */ #define CREATE_LINKMAP 0xFFFFFFFF /*--------------------------------*/ /* Multi-byte word access macros */ #if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */ #define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr)) #define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr)) #define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val) #define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val) #else /* Use byte-by-byte access to the FAT structure */ #define LD_WORD(ptr) (WORD)(((WORD)*((BYTE*)(ptr)+1)<<8)|(WORD)*(BYTE*)(ptr)) #define LD_DWORD(ptr) (DWORD)(((DWORD)*((BYTE*)(ptr)+3)<<24)|((DWORD)*((BYTE*)(ptr)+2)<<16)|((WORD)*((BYTE*)(ptr)+1)<<8)|*(BYTE*)(ptr)) #define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8) #define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8); *((BYTE*)(ptr)+2)=(BYTE)((DWORD)(val)>>16); *((BYTE*)(ptr)+3)=(BYTE)((DWORD)(val)>>24) #endif #ifdef __cplusplus } #endif #endif /* _FATFS */ 根据头文件修改一下
06-17
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值