Vala vapi файлы документации - PullRequest
11 голосов
/ 23 марта 2010

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

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

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

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

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

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

Ответы [ 4 ]

15 голосов
/ 25 марта 2010

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

example.vala может быть

using MyFunc;

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

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

1 голос
/ 13 апреля 2014

Для библиотек на основе 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.

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

1 голос
/ 03 ноября 2010

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

0 голосов
/ 24 декабря 2010

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

...