valavapi

Can the free_function be a static class method?


This is a follow-up question to How to write void pointer typedefs in vapi files?

I now have four almost identical [Compact] classes that represent handles allocated with unixODBCs SQLAllocHandle function.

The first one (for the ENV type handle) looks like this:

[CCode (cname = "void", free_function = "EnvironmentHandle.free")]
[Compact]
public class EnvironmentHandle {
    [CCode (cname = "SQLAllocHandle")]
    private static Return allocate_internal (HandleType type, void* nothing, out EnvironmentHandle output_handle);
    public static Return allocate (out EnvironmentHandle output_handle) {
        return allocate_internal (HandleType.ENV, null, out output_handle);
    }
    [CCode (cname = "SQLFreeHandle")]
    private static Return free_internal (HandleType type, EnvironmentHandle handle);
    public static Return free (EnvironmentHandle handle) {
        return free_internal (HandleType.ENV, handle);
    }
}

This doesn't compile.

Is it possible to use a static class method as the free_function?

If not, is there at least a way to write a custom free_function in the vapi file?

I need a custom function because the SQLFreeHandle function takes the handle type and the handle as an argument.

From the vapi users perspective all that is really important is:

[CCode (cname = "void")]
[Compact]
public class EnvironmentHandle {
    public static Return allocate (out EnvironmentHandle output_handle);
}

The only other solution would be to use a [SimpleType] struct as suggested by apmasell in the original question. That would hide the fact that a SQLHANLDE is really a reference type.

The full code of my current implementation is available online: https://github.com/antiochus/unixodbc-vala/tree/0486f54dc3f86d9c8bf31071980e4f171aca9591


Solution

  • No. The free_function is a C function, not a Vala function and it cannot take any context. You have two options:

    1. Write a C macro in an extra header file to do what you want and bind the macro as the free function.
    2. Bind the free function as a static method that takes an owned instance of the object:

      [CCode (cname = "SQLFreeHandle")] public static Return free(HandleType type, owned EnvironmentHandle handle);

      EnvrionmentHandle foo = ...; EnvironmentHandle.free(HandleType.ENV, (owned) foo);