实施共享库/模块 - 参数结构不在 headers 中

Implementing shared library / module - argument struct not in headers

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

为此,我从 LVM2 的源代码着手,特别是外部锁定机制的实现,可以在 here.

中找到

基本上,我发现我需要做的是使用如下描述的 header 实现功能:

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 源代码中找到(而且它相当复杂!),但它不在包公开的 headers 中作为 API(例如 lvm2-在 RHEL7 中开发包)。正如我想象的那样(我绝对不是最好的 C 程序员),因为该结构应该由外部库使用,所以它必须在 headers.

我的想法是错误的还是只是 "bug" 我应该与 LVM2 开发人员讨论?除了 copy/pasting 该结构和它依赖于我项目中的 header 文件的所有其他类型之外,是否有任何解决方法?这样做 "workaround",是否会以任何方式破坏 GNU GPL 许可证?

您链接的源文件间接包含 config.h header 其中有这一行:

struct cmd_context;

这告诉 C 编译器有一个 struct 具有该名称。这就是编译器生成正确机器代码所需知道的全部内容。

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

但是只要你把它当作一个 opaque data type 在函数内外传递一个指向它的 known-size 指针,就可以了。这称为前向声明,是在 C 中实现封装的主要方式(检查 stdio 的 FILE)。