Vala vapi files documentation

久未见 提交于 2019-12-04 01:32:57
elmarco

Yes, to call a C function, you need to write a binding for it. The process is described in http://live.gnome.org/Vala/Tutorial#Binding_Libraries_with_VAPI_Files, however, this doesn't apply directly to custom functions or libraries written without GObject. You'll probably need help from #vala IRC channel if you have complex binding for non-GObject libraries.

However, most of the time, we use simple vapi files to bind some autoconf define or some functions written in plain C, for efficiency reason or broken vala, or whatever other reason. And this is the way that most people do:

myfunc.vapi

[CCode (cheader_filename = "myfunc.h")]
namespace MyFunc {
    [CCode (cname = "my_func_foo")]
    public string foo (int bar, Object? o = null);
}

myfunc.h (and corresponding implementation in a .c linked with your project)

#include <glib-object.h>
char* my_func_foo(int bar, GObject* o)

example.vala could be

using MyFunc;

void main() {
    baz = foo(42);
}

When compiling with valac, use --vapidir= to give the directory location of the myfunc.vapi. Depending on your build system, you may need to pass extra argument to valac or gcc CFLAGS in order to link everything together.

Jim Nelson

The only addition I would make to elmarco's answer is the extern keyword. If you're trying to access a single C function that's already available in one of your packages or the standard C/Posix libraries, you can access it easily this way.

For GLib-based libraries written in C you can try to generate gir-files from your C-sources: Vala/Bindings.

Doing it manually is no problem too. Suppose you have a library which defines SomelibClass1 in C with a method called do_something which takes a string. The name of the headerfile is "somelib.h". Then the corresponding vapi is as simple as the following:

somelib.vapi:

[CCode (cheader_filename="somelib.h")]
namespace Somelib {
   public class Class1 {
      public void do_something (string str);
   }
}

Documentation for writing vapis for non-GLib libraries can be found here: Vala/LegacyBindings

This is actually really easy. Lets take an excerpt from posix.vapi:

[Compact]
[CCode (cname = "FILE", free_function = "fclose", cheader_filename = "stdio.h")]
public class FILE {
    [CCode (cname = "fopen")]
    public static FILE? open (string path, string mode);

    [CCode (cname = "fgets", instance_pos = -1)]
    public unowned string? gets (char[] s);
}

This implements the following C-Function:

FILE *fopen (const char *path, const char *mode);
char *fgets (char *s, int size, FILE *stream);

When discarding the instance_pos attribute vala assumes that the object is the first parameter to a method. This way it is possible to bind c-constructs that are roughly object-oriented. The free_method of the compact-class is called when the object is dereferenced.

The CCode(cname)-attribute of a method, class, struct, etc. has to be the name of it as it would be in C.

There is a lot more to this subject, but this should give you a general overview.

It would probably be easier to just access your vala code from c. As all you have to do is just compile to C.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!