Title in text due to discourse bug

discourse says: Title seems unclear, is it a complete sentence?

g_irepository_get_shared_library – why return multiple names?

The returned name is used by the Nim bindings to access the libraries, I think Nim uses dlopen() for that. For most libs g_irepository_get_shared_library() returns a single name. But for GTK3 and glib we get two:

$ grep -A1 "# libraries:" ~/.nimble/pkgs/gintro-0.8.2/gintro/* | grep ","
/home/salewski/.nimble/pkgs/gintro-0.8.2/gintro/glib.nim-# libgobject-2.0.so.0,libglib-2.0.so.0
/home/salewski/.nimble/pkgs/gintro-0.8.2/gintro/gtk.nim-# libgtk-3.so.0,libgdk-3.so.0

But for GTK4 only one. So first question: Why more than one at all.

Some years ago when I started with the bindings I just took the first one, and it worked. Now due to the libnice support request I looked at the generated binding modules again and noted that using the first name is OK for gtk, dlopen() seems to fail when I would use the second lib name. That is expected.

But for glib my choice should be wrong. But still it has worked in the last 4 years for all people, and indeed both lib names are working in the same way.

So I looked at the contained symbols with

nm -D /usr/lib64/libgobject-2.0.so.0 | grep g_list_free
                 U g_list_free

So libgobject lists the glib symbols with the U tag. Is that the reason why libgobjects seems to work like libglib for use with dlopen?

1 Like

I have tried to fix the title, but is does not work. No idea why.

Looking at the gir files we have indeed:

$ head -15 /usr/share/gir-1.0/GLib-2.0.gir 
<?xml version="1.0"?>
<!-- This file was automatically generated from C sources - DO NOT EDIT!
To affect the contents of this file, edit the original C definitions,
and/or use gtk-doc annotations.  -->
<repository version="1.2"
            xmlns="http://www.gtk.org/introspection/core/1.0"
            xmlns:c="http://www.gtk.org/introspection/c/1.0"
            xmlns:glib="http://www.gtk.org/introspection/glib/1.0">
  <package name="glib-2.0"/>
  <c:include name="glib.h"/>
  <namespace name="GLib"
             version="2.0"
             shared-library="libgobject-2.0.so.0,libglib-2.0.so.0"
             c:identifier-prefixes="G"
             c:symbol-prefixes="g,glib">

$ head -25 /usr/share/gir-1.0/Gtk-3.0.gir 
<?xml version="1.0"?>
<!-- This file was automatically generated from C sources - DO NOT EDIT!
To affect the contents of this file, edit the original C definitions,
and/or use gtk-doc annotations.  -->
<repository version="1.2"
            xmlns="http://www.gtk.org/introspection/core/1.0"
            xmlns:c="http://www.gtk.org/introspection/c/1.0"
            xmlns:glib="http://www.gtk.org/introspection/glib/1.0">
  <include name="Atk" version="1.0"/>
  <include name="Gdk" version="3.0"/>
  <include name="xlib" version="2.0"/>
  <package name="gtk+-3.0"/>
  <c:include name="gtk/gtk-a11y.h"/>
  <c:include name="gtk/gtk.h"/>
  <c:include name="gtk/gtkx.h"/>
  <namespace name="Gtk"
             version="3.0"
             shared-library="libgtk-3.so.0,libgdk-3.so.0"
             c:identifier-prefixes="Gtk"
             c:symbol-prefixes="gtk">

So for gtk libgtk-3.so.0 is listed first. But for glib libgobject-2.0.so.0 is listed first.

I just tested with the dlopen example from

https://tldp.org/HOWTO/Program-Library-HOWTO/dl-libraries.html

#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>

int main(int argc, char **argv) {
void *handle;
char  *(*dir)();
char *error;

handle = dlopen ("libgobject-2.0.so.0", RTLD_LAZY);
if (!handle) {
    fputs (dlerror(), stderr);
    exit(1);
}

dir = dlsym(handle, "g_get_current_dir");
if ((error = dlerror()) != NULL)  {
    fputs(error, stderr);
    exit(1);
}

printf ("%s\n", (*dir)());
dlclose(handle);
}

Output is

$ gcc -o foo foo.c -ldl
salewski@nuc /tmp/hhh $ ./foo 
/tmp/hhh

So gobject library provides at least some of the glib functions.

And for the problem with multiple names returned by g_irepository_get_shared_library() I think I will use the Levenshtein edit-distance to pic the one which matches best with the namespace.

Yes, since libgobject-2.0 links against libglib-2.0, but depending on the linker it might not be enough when dlopening.

You should always dlopen() all the libraries listed in the comma-separated value of the shared-library attribute. That is the behaviour of libgirepository, and it’s the expected functionality of the attribute.

If the shared-library attribute is empty, on the other hand, it is implied that you should dlopen() the main program and look in the global address space—i.e. pass NULL for the file name argument.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.