实现共享库/模块 - 不在头文件中的参数结构

时间:2016-07-09 15:52:40

标签: c linux lvm

我正在尝试为LVM实现自定义锁定库。在理论上,在lvm.conf中将locking_type设置为external(2)并提供实现所需函数的共享库似乎足够且相对简单。

调查一下我开始使用LVM2的源代码,特别是外部锁定机制实现,可以找到here

基本上,我发现我需要做的是使用如下所述的标题实现函数:

static void (*_reset_fn) (void) = NULL;
static void (*_end_fn) (void) = NULL;
static int (*_lock_fn) (struct cmd_context * cmd, const char *resource, uint32_t flags) = NULL;
static int (*_init_fn) (int type, struct dm_config_tree * cft, uint32_t *flags) = NULL;
static int (*_lock_query_fn) (const char *resource, int *mode) = NULL;

现在,到目前为止,一切都很好。但是,查看_lock_fn定义,它会将struct cmd_context指针作为第一个参数。该结构很容易在LVM2源中找到(并且它是一个相当复杂的结构!),但它不在包作为API公开的头部内(例如RHEL7中的lvm2-devel包)。正如我想象的那样(我绝对不是最好的C程序员),因为该结构应该被外部库使用,所以它必须在标题中。

我认为这是错误的,还是只是一个"错误"我应该与LVM2开发人员讨论?是否有任何变通方法,除了复制/粘贴结构和它依赖于我的项目中的头文件的所有其他类型?这样做"解决方法",它是否以任何方式打破了GNU GPL许可?

1 个答案:

答案 0 :(得分:2)

您链接的源文件间接包含config.h标题,该标题包含以下行:

struct cmd_context;

这告诉C编译器有一个struct具有该名称。所有编译器都需要知道生成正确的机器代码。

如果您要访问该结构的成员或直接创建它的对象,您将得到错误,因为编译器不知道结构的大小或成员。

但是只要你将它用作opaque data type将一个已知大小的指针传入和传出函数,你就可以了。这称为前向声明,是在C中实现封装的主要方式(检查stdio' s FILE)。