如何在多个翻译单元之间共享不透明类型?

时间:2018-11-27 05:32:44

标签: c linux struct

我正在开发自己的C项目,并且需要一些design / common_C_idiom建议。我要解决的问题是打开已配置设备的输入日期流。但是我要保持配置和设备分开。这是我尝试过的:

  1. 配置:

config.h

#ifndef CONFIG_H
#define CONFIG_H

typedef struct config_t config_t;

config_t* config_t_allocate(void);
void config_t_free(config_t *);
//functions to set configuration parameters

#endif //CONFIG_H

config.c

#include <stdlib.h>
#include "device.h"

struct config_t{
    const char * name;
};

config_t* config_t_allocate(void){
    return malloc(sizeof(config_t));
}

void config_t_free(config_t * config_ptr){
    free(config_ptr);
}
  1. 设备:

device.h

#ifndef DEVICE_H
#define DEVICE_H

typedef struct config_t config_t;

typedef struct device_t device_t;

void configure_device(device_t**, config_t*);

//other device-related methods

#endif //DEVICE_H

device.c

#include "device.h"
#include <sys/fcntl.h>

struct device_t{
    int fd;
};

//Does not compile. What is the confit_t type?
void configure_device(device_t** device, config_t* config_ptr){
    *device = malloc(sizeof(**device));
    (*device) -> fd = open(config_ptr -> name, O_RDONLY);
}

因此,我想在多个翻译单位之间共享以config_t完成的config.c类型。我唯一可以想象的就是创建一个包含该结构的 “ private” 头文件。像这样: types/configdef.h

#ifndef TYPES_CONFIG_DEF_H
#define TYPES_CONFIG_DEF_H

struct config_t{
    const char * name;
};

#endif //TYPES_CONFIG_DEF_H

并在需要config_t的任何地方添加它。

1 个答案:

答案 0 :(得分:5)

如果您使用诸如config_t之类的不透明类型,则可以放弃直接在源代码中访问其成员的选项,而该源代码并不涉及实现细节。但是,您可以提供一个执行此操作的功能:

extern const char *config_t_get_name(config_t *config);
在{{1}中声明的,在config.h中声明的

或其附近,在config.c中使用。

  

但是如何将device.c放入某个我不会公开的头文件中(某种私有库),并在实现C文件中的任何地方使用它。是不是很常见或有一些缺点?

实际上,访问功能的主要替代方法是“专用”标头,但这通常不如访问功能好。可以办到;这并不完全不常见,特别是如果需要访问结构内部的功能套件太大而无法合理地容纳在单个源文件中(或者因为本地规则是“每个源文件一个非静态功能”,或者…)。因此,困难在于确保不应该专用于私有头的文件不能(不)使用它。这表明私有标头不应与库一起安装,并且私有标头可能应与项目的公共标头位于单独的目录中。

考虑是否应该执行:

struct config_t{ const char * name; };

然后,您可以通过使用 #include "project/headerX.h" // General, public headers for the project #include "project/private/internal.h" // Private headers for limited use 或等效名称来查找不应允许的引用,从而对专用标头的使用进行监管,等等。或者,或者结合使用,为专用标头使用独特的命名方案,使用grep前缀表示“私有”:

pvt_

主题有无尽的变化。程序员将设计出各种方案来访问专用标头以使用它们。最终,您必须信任您的程序员来遵守规则-您不得使用私有标头,除非在明确授予使用它们的权限的文件中。如果他们不能接受该纪律,那么也许他们根本不应该参与该项目。或者,也许您应该花些时间来理解为什么顽强的程序员不能使用您提供的访问功能-设计有问题吗?

您可以在Google(或您选择的搜索引擎)上搜索“ #include "project/internal/pvt_config.h" ”;结果似乎是有益的。添加您选择的语言(C ++,Java,JavaScript占主导地位; C没那么突出,但确实会提取引用可能会有所帮助)。