GByteArray element type information from typelib files



I'm writing a language binding using gobject-introspection and have noticed some unexpected behaviour when extracting GByteArray element type information from typelib files. When multiple functions with GByteArray arguments share similar argument names it appears that the first such function appearing in the GIR file determines the element type for all other such functions.

As an example, consider the following:

$ cat test.h

#include <glib-object.h>

void test_func1 (GByteArray* v);
void test_func2 (GByteArray* v);

$ cat test.c

#include "test.h"

/**
 * test_func1:
 * @v: (element-type gint8):
 */
void
test_func1 (GByteArray *v)
{
}

/**
 * test_func2:
 * @v: (element-type guint8):
 */
void
test_func2 (GByteArray *v)
{
}


Notice that test_func1 and test_func2 are identical except for the element-type annotation - test_func1 specifies a gint8 element type; test_func2 specifies a guint8 element type. Both functions name their argument 'v' in the header file.


I created a typelib file and used a small program to extract type information:

$ gcc -shared $(pkg-config --cflags gobject-2.0) -o libtest-1.0.so test.c $(pkg-config --libs gobject-2.0)

$ CC=gcc CFLAGS=$(pkg-config --cflags gobject-2.0) g-ir-scanner --warn-all --quiet --namespace=Test --nsversion=1.0 --symbol-prefix=test --no-libtool --library=test-1.0 --output=Test-1.0.gir test.h test.c

$ g-ir-compiler Test-1.0.gir -o Test-1.0.typelib

$ cat query.c

#include <girepository.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
    GIBaseInfo *base_info;
    GIArgInfo *arg_info;
    GITypeInfo *type_info;
    GITypeTag type_tag;
    GError *error = NULL;

    if ( argc != 2 )
    {
        printf("usage %s <function name>\n", argv[0]);
        return -1;
    }

        g_irepository_require_private(NULL, ".", "Test", NULL, 0, &error);
    if ( error )
    {
        printf("ERROR: %s\n", error->message);
        g_error_free(error);
        return -1;
    }

    base_info = g_irepository_find_by_name(NULL, "Test", argv[1]);
    if ( !base_info )
    {
        printf("entry %s not found\n", argv[1]);
        return -1;
    }

    if ( !GI_IS_FUNCTION_INFO(base_info) )
    {
        printf("expected function info\n");
        return -1;
    }
    printf("function name: %s\n", g_base_info_get_name(base_info));

    arg_info = g_callable_info_get_arg(base_info, 0);
    type_info = g_arg_info_get_type(arg_info);
    type_tag = g_type_info_get_tag(type_info);
    printf("arg type: %s\n", g_type_tag_to_string(type_tag));

    type_info = g_type_info_get_param_type(type_info, 0);
    type_tag = g_type_info_get_tag(type_info);
    printf("array element type: %s\n", g_type_tag_to_string(type_tag));

    return 0;
}

$ gcc -o query query.c $(pkg-config --cflags gobject-introspection-1.0) $(pkg-config --libs gobject-introspection-1.0)


Querying the typelib returns the element type of func1 for both func1 and func2:

$ ./query func1
function name: func1
arg type: array
array element type: gint8

$ ./xxx func2
function name: func2
arg type: array
array element type: gint8


This behaviour seems restricted to GByteArray types; other array types return the correct element type.

It seems odd to me to specify anything other than a guint8 element type for GByteArray args, but this unexpected behaviour was picked up when extending some of the GByteArray test cases in the gimarshallingtest.c file. At the moment the GByteArray functions in the GIMarshallingTests-1.0.typelib file all use guint8 element types by virtue of the gi_marshalling_tests_bytearray_full_return() appearing first in the GIR file. Adding a gi_marshalling_tests_bytearray_full_in() test case based on gi_marshalling_tests_bytearray_none_in() is enough to cause all GByteArray functions in the marshalling test typelib all use gint8 element types.


Thanks

Keri


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]