【发布时间】:2014-02-10 20:07:33
【问题描述】:
我想做一些看似不可能的事情。
我要写 3 个文件:main.c、foo.h、foo.c。
这个想法是在 foo.h 或 foo.c 中定义一个结构,使其成员在 main.c 中可见。其中一个结构成员的类型为FILE,如标准头<stdio.h> 中所定义。但是<stdio.h> 的函数和宏必须在文件 main.c 中保持不可见。
该解决方案必须符合标准 C(C99 和/或 C11)并且可移植。 这可能吗?
foo.h 标头在 main.c 和 foo.c 中都#included。
标准头 <stdio.h> 仅在 foo.c 中包含 #include,但在 main.c 中不包含。
我想声明一个struct如下:
struct myfile_s {
FILE *F;
char *filename;
char buff[100];
} myfile;
对于接下来的内容,只有成员 FILE *F 很重要。
struct myfile 将被 foo.c 中出现的函数初始化和修改。
目的是通过 foo.h 中声明的 extern 函数对 myfile 进行文件操作,而这些函数又必须在 foo.c 中定义。 p>
文件操作涉及<stdio.h>的标准函数,但这些函数必须隐藏在文件main.c中。
但是,我想从 main.c 直接访问myfile 的成员。
这意味着struct myfile_s 的定义必须在foo.h 中完成(也就是说,它不能通过使用不完整结构声明的技巧来“延迟”,例如struct myfile_s ;)。
简而言之,我希望 FILE 类型在 main.c 和/或 foo.h 中可见,但其余的 <stdio.h> 声明为他们隐藏。
另一个限制:直接复制由<stdio.h> 提供的FILE 的定义的想法是不可取的,因为代码必须是可移植的。
我的第一次尝试是将 struct myfile 隐藏在 foo.c 中。
代码是:
foo.h
struct myfile_s;
struct myfile_s myfile;
extern void startfile(struct myfile *f);
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...
}
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;
}
延迟的struct myfile_s 声明避免了在foo.h 中包含<stdio.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);
foo.c
#include <stdio.h>
#include "foo.h"
void startfile(struct myfile *f)
{
// Do some stuff...
}
【问题讨论】:
-
使用两个不同的标题还不够吗?一个内部头文件和一个外部?外部只知道 void 指针(或者在您的情况下是结构的 FILE 指针部分)和内部您将这些 void 指针转换为您的类型,因此具有内部头文件的人知道您要保留的部分内部和外部头 jsut 显示你想给什么。
-
您是否尝试在
foo.h中包含<stdio.h>,即您定义结构的位置...我更喜欢在标题中声明它 -
第二种方法有什么问题?它看起来大部分都在正确的轨道上。
-
@MichaelAaronSafyan:因为
FILE类型定义在<stdio.h>中,它包含在foo.c中但不在foo.h中。这个想法是<stdio.h>的功能必须在文件main.c中不可见。 -
将
#define FILE void添加到您的主目录。可能会有所帮助(但承认有点麻烦)。这当然是在包含 foo.h 之前
标签: c