我想做一些看似不可能的事情.
我想写3个文件:main.c,foo.h,foo.c.
我们的想法是在foo.h或foo.c中定义一个结构,使其成员在main.c中可见.其中一个struct成员具有FILE标准头中定义的类型<stdio.h>.但是<stdio.h>必须在main.c文件中保持不可见的函数和宏.
该解决方案必须符合标准C(C99和/或C11)和便携式.那可能吗?
标题foo.h在main.c和foo.c中都是#included .
标准头文件<stdio.h>仅在foo.c中包含#included ,但在main.c中不包含.
我想声明struct如下:
struct myfile_s {
FILE *F;
char *filename;
char buff[100];
} myfile;
Run Code Online (Sandbox Code Playgroud)
对于以下内容,只有成员FILE *F才是重要的.
结构myfile将由foo.c中出现的函数初始化和修改.
目的是myfile通过foo.h中extern声明的函数对文件进行操作,而foo.h中的函数又必须在foo.c中定义.
文件操作涉及标准函数<stdio.h>,但这些函数必须隐藏在main.c文件中.但是,我想直接从main.c访问到成员myfile.这意味着struct myfile_s必须在foo.h中完成定义(也就是说,它不能被"延迟"使用不完整的结构声明的技巧,例如struct myfile_s ;).
简而言之,我希望类型FILE在main.c和/或foo.h中可见,但其余的<stdio.h>声明对它们保持隐藏.
另一个限制:直接复制"手头" FILE提供的定义的想法<stdio.h>是不可取的,因为代码必须是可移植的.
我的第一次尝试是struct myfile通过将其写入foo.c来隐藏它.
代码是:
foo.h中
struct myfile_s;
struct myfile_s myfile;
extern void startfile(struct myfile *f);
Run Code Online (Sandbox Code Playgroud)
foo.c的
#include <stdio.h>
#include "foo.h"
struct myfile_s {
FILE *F;
char *filename;
char buff[100];
} myfile;
void startfile(struct myfile *f)
{
// Do some stuff...
}
Run Code Online (Sandbox Code Playgroud)
main.c中
#include "foo.h"
int main(void)
{
myfile.F = NULL; // This kind of access bring error, but I want to do it anyway!!
startfile(&myfile);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
延迟struct myfile_s声明避免了<stdio.h>在foo.h中包含的需要,因此标题工作正常,但结构类型仍然不完整,因此myfile.F无法在main.c中完成访问.
那么: 我如何访问myfile.F?
我尝试了另一种方式,当然,也给出了错误:
foo.h中
struct myfile_s {
FILE *F;
char *filename;
char buff[100];
} myfile;
extern void startfile(struct myfile *f);
Run Code Online (Sandbox Code Playgroud)
foo.c的
#include <stdio.h>
#include "foo.h"
void startfile(struct myfile *f)
{
// Do some stuff...
}
Run Code Online (Sandbox Code Playgroud)
struct myfile_s {
void *pPrivateThings; // This could be the FILE* or another private structure
char *filename;
char buff[100];
} myfile;
Run Code Online (Sandbox Code Playgroud)
我会在创建时分配另一个私有结构:
struct myprivatefile_s {
FILE *F;
// You could add other fields here that are not public
} myprivatefile;
myprivatefile *privateThings = malloc(sizeof(myprivatefile));
myfile.pPrivateThings = privateThings;
privateThings->F = fopen();
Run Code Online (Sandbox Code Playgroud)
通过这种方式,您可以继续添加不需要对您的内容可见(即私有)的内容.
这一切都是不必要的复杂,不是吗?
看起来好像你真的不知道自己想要什么.为什么你想拥有的单个实例myfile中foo.h?你为什么要myfile.F明确设置main?为什么不写像一个功能myfile_init对于在foo.c,它具有完全访问权限?
我会做一个opaque结构的typedef foo.h,定义东西并实现构造函数和访问器函数foo.h,然后创建一个myfilein 的实例main.c:
foo.h中
typedef struct Myfile Myfile;
Myfile *myfile_open(const char *filename);
myfile_process(Myfile *f, ...);
int myfile_close(Myfile *f);
Run Code Online (Sandbox Code Playgroud)
foo.c的
#include <stdio.h>
struct Myfile {
FILE *f;
...
};
// implement myfile_xxx functions
Run Code Online (Sandbox Code Playgroud)
main.c中
#include "foo.h"
int main()
{
Myfile *f = myfile_open("rhubarb.txt");
if (f == NULL) exit(1);
myfile_process(f, ...);
myfile_close(f);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
无需部分包含其他标头.通过移动初始化myfile_open,一切都被巧妙地封装在其中foo.c.主程序只看到句柄.FILE *真的像标准手柄一样.
| 归档时间: |
|
| 查看次数: |
171 次 |
| 最近记录: |