Документация файлов Vala vapi

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

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

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

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

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

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

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

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

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

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

Единственное дополнение, которое я бы сделал для ответа Elmarco, – это ключевое слово 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 для библиотек non-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_mode компактного classа вызывается, когда объект разыменовывается.

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

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

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