2016-07-09 23 views
0

Ich versuche, eine benutzerdefinierte Sperrbibliothek für LVM zu implementieren. Das Festlegen von locking_type auf external (2) in lvm.conf und das Bereitstellen einer gemeinsamen Bibliothek, die die erforderlichen Funktionen implementiert, erscheint theoretisch ausreichend und relativ einfach.Implementieren von shared library/module - argument struct nicht in headern

Blick in diese ich begann mit den Quellen für LVM2, speziell die externe Sperrmechanismus-Implementierung, die here gefunden werden kann.

Im Grunde, was ich herausgefunden, dass ich tun muss, ist mit den wie folgt beschriebenen Header-Funktionen implementieren:

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; 

nun alles peachy bis zu diesem Punkt. Betrachtet man jedoch die _lock_fn-Definition, wird ein Zeiger auf struct cmd_context als erstes Argument benötigt. Diese Struktur kann leicht in den LVM2-Quellen gefunden werden (und sie ist ziemlich komplex!), Aber sie befindet sich nicht innerhalb der Header, die vom Paket als API bereitgestellt werden (z. B. das Paket lvm2-devel in RHEL7). Wie ich mir vorstelle (ich bin definitiv nicht der beste C-Programmierer), da diese Struktur von externen Bibliotheken verwendet werden soll, ist es zwingend erforderlich, dass sie in den Headern sein sollte.

Denke ich das falsch oder ist es nur ein "Bug" und ich sollte mit LVM2 Entwickler diskutieren? Gibt es irgendwelche Problemumgehungen, außer dem Kopieren/Einfügen dieser Struktur und allen anderen Typen, von denen sie abhängig ist von einer Header-Datei in meinem Projekt? Führt diese "Workaround", bricht die GNU GPL-Lizenz in irgendeiner Weise?

+0

Siehe auch Fragen zu 'opaken Zeigertypen' usw. Das scheint hier zu sein. Sie sind eine gute Idee, wenn der aufrufende Code nicht über die Interna der Struktur Bescheid wissen muss - oder Instanzen der Struktur als lokale oder globale Variablen zuweisen müssen. Solange ein Zeiger allein ausreicht, sind opake Typen gut. –

Antwort

2

Die Quelldatei verknüpft ist, enthält indirekt die config.h Header, der diese Zeile hat:

struct cmd_context; 

Dies teilt die C-Compiler, dass es eine struct mit diesem Namen ist. Das ist alles, was der Compiler wissen muss, um den richtigen Maschinencode zu generieren.

Wenn Sie auf Mitglieder dieser Struktur zugreifen oder direkt ein Objekt daraus erstellen würden, würden Sie Fehler erhalten, weil der Compiler die Größe oder Mitglieder der Struktur nicht kennt.

Aber solange Sie es als opaque data type verwenden, übergeben Sie einen bekannten Zeiger auf es in und aus Funktionen, Sie sind in Ordnung. Dies wird als Vorwärtsdeklaration bezeichnet und ist eine primäre Möglichkeit, eine Kapselung in C zu erreichen (siehe FILE von stdio).