Valac отсутствует сгенерированный заголовок

У меня есть два файла, client.vala а также lib.vapi,
VAPI определяет класс (который обычно говорит с кодом C):

class Toplevel.Sub.CClass
{
    public uint i;
}

А также client.vala использует класс:

class Toplevel.Sub.UserClass
{
    public Toplevel.Sub.CClass c_class;
}

int main()
{
    var cls = new Toplevel.Sub.UserClass();
    cls.c_class.i = 0;
    return 0;
}

Когда я пытаюсь скомпилировать программу, я получаю сообщение об ошибке:

$ valac client.vala lib.vapi
/tmp/bug/client.vala.c:7:20: fatal error: client.h: No such file or directory
compilation terminated.
error: cc exited with status 256
Compilation failed: 1 error(s), 0 warning(s)

Компилятор, кажется, хочет сгенерировать заголовок для функций в client.vala,

Это ошибка или я что-то упустил?

1 ответ

Решение

Вы обнаружили то, чего я не знал о компиляторе Vala. client.h является именем заголовка C по умолчанию, сгенерированным компилятором, когда альтернативы не предоставлено. Он использовал базовое имя исходного файла Vala. Вы можете изменить это, используя cheader_filename CCode подробно. Измените то, что у вас есть в вашем VAPI:

[CCode (cheader_filename = "my_real_c_header.h")]
class Toplevel.Sub.CClass
{
    public uint i;
}

и вы увидите, что включить сейчас #include "my_real_c_header.h"

Кстати, если вы компилируете с valac client.vala --vapididr . --pkg lib вы увидите, что заголовок включен как #include <my_real_c_header.h>, Лично я думаю, что VAPI следует использовать с --pkg вариант.

Если вы буквально используете Toplevel.Sub.CClass "обычно говорите с кодом C", тогда вы неправильно поняли цель VAPI. Я говорю "говорить с", чтобы означать вызов различных функций C и сбор результатов, чтобы они могли быть представлены в более дружественном для Vala виде для остальной части вашей программы. Так что это интерфейс оболочки.

VAPI содержит инструкции для компилятора Vala для перевода имен в правильные имена для интерфейса C. Например, у вас может быть очень простая функция C, void top_level_do_something (), что вы хотите использовать в Вала. В Vala это помогает использовать пространство имен, чтобы VAPI мог быть:

[CCode (cheader_filename = "my_real_c_header.h")]
namespace TopLevel {
    [CCode (cname = "top_level_do_something")]
    public void do_something ();
}

Затем вы можете позвонить в Вала с TopLevel.do_something () и компилятор записал бы это как top_level_do_something () в С.

Посмотрите на Написание VAPI вручную для более подробной информации.

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