Vala vapi файлы документации

Я хотел бы взломать существующий C-проект на базе GLib с использованием Vala.

По сути, в начале процесса сборки я использую valac для генерации файлов.c и.h из моих файлов.vala, а затем просто компилирую сгенерированные файлы так же, как любой другой файл.c или.h.

Это, вероятно, не лучший способ, но, по-видимому, по большей части работает нормально.

Моя проблема в том, что мне трудно получить доступ к существующему коду C из кода Vala. Есть простой способ сделать это?

Я пытался написать свои собственные файлы.vapi (мне не повезло с инструментом, поставляемым с vala), но я не могу найти достойную документацию о том, как их написать.

Кто-нибудь существует? Нужен ли мне один из этих файлов для вызова существующего кода C?

4 ответа

Да, чтобы вызвать функцию C, вам нужно написать привязку для нее. Процесс описан в http://live.gnome.org/Vala/Tutorial, однако это не относится непосредственно к пользовательским функциям или библиотекам, написанным без GObject. Вам, вероятно, понадобится помощь из IRC-канала #vala, если у вас есть сложное связывание для библиотек, не относящихся к GObject.

Тем не менее, в большинстве случаев мы используем простые vapi-файлы для привязки некоторого определения autoconf или некоторых функций, написанных на простом C, из соображений эффективности, из-за неработоспособности или по любой другой причине. И так делают большинство людей:

myfunc.vapi

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

myfunc.h (и соответствующая реализация в.c связана с вашим проектом)

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

пример.вала может быть

using MyFunc;

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

При компиляции с помощью valac используйте --vapidir= указать местоположение каталога myfunc.vapi. В зависимости от вашей системы сборки вам может потребоваться передать дополнительный аргумент в valac или gcc CFLAGS, чтобы связать все вместе.

Единственное дополнение, которое я бы сделал к ответу Эльмарко, это extern ключевое слово. Если вы пытаетесь получить доступ к одной функции C, которая уже доступна в одном из ваших пакетов или в стандартных библиотеках C/Posix, вы можете легко получить к ней доступ таким образом.

Для библиотек на основе GLib, написанных на C, вы можете попытаться сгенерировать gir-файлы из ваших C-источников: Vala / Bindings.

Делать это вручную тоже не проблема. Предположим, у вас есть библиотека, которая определяет SomelibClass1 в C с помощью метода do_something, который принимает строку. Название файла заголовка - "somelib.h". Тогда соответствующий vapi так же прост:

somelib.vapi:

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

Документацию по написанию vapis для библиотек не-GLib можно найти здесь: Vala / LegacyBindings

Это на самом деле очень просто. Давайте возьмем выдержку из 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);
}

Это реализует следующую C-функцию:

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

При отбрасывании атрибута instance_pos vala предполагает, что объект является первым параметром метода. Таким образом, можно связать c-конструкции, которые являются примерно объектно-ориентированными. Free_method компактного класса вызывается, когда объект разыменовывается.

Атрибут CCode(cname) метода, класса, структуры и т. Д. Должен быть таким же, как в C.

В этом вопросе есть еще много чего, но это должно дать вам общий обзор.

Вероятно, было бы проще получить доступ к вашему коду Vala из c. Как все, что вам нужно сделать, это просто скомпилировать в C.

Другие вопросы по тегам