首页 > 解决方案 > 如何将 Vala 编译为 C 并调用另一个文件中的函数,该文件最初是用 C 编写的并全部编译?

问题描述

似乎没有关于与最初用 C 编写的 C 源代码互操作的文档。

或者,最好从 vala 代码创建一个库并从我的 C 程序中调用它?

如何在 Vala 中导入其他文件?

似乎回答了我的问题,我会在几个小时内检查。

标签: vala

解决方案


这是一个非常简单的例子。将以下 C 代码另存为名为a.c

#include <stdio.h>

void my_function() {
    printf("I am a function written in a C file\n");
}

将以下 Vala 代码另存为名为b.vala

extern void my_function ();

void main() {
    my_function();
}

然后编译:

valac a.c b.vala --output demo

这里的幕后发生了很多事情。valac完成工作,但是像 Meson 这样的构建系统更适合于一个将要增长的项目。

首先valac识别列表中的 Vala 文件并将其编译为 C。这extern void my_function ();告诉 Vala 编译器my_function是在外部定义的,而不是在给定的任何 Vala 源文件中。Vala 编译器只需要函数签名来检查来自 Vala 的任何调用并在生成的 C 文件中声明函数。而不是将extern每个可以写入接口文件的位置放置。在 Vala 中,这是一个VAPI 文件。VAPI 将 Vala 符号到 C 符号的转换信息保存在一处,因此有助于项目的可维护性和可读性。

其次valac将给定的 C 文件和生成的 C 文件传递​​给 C 编译器。C 编译器将文件编译为目标文件,然后调用链接器来构建单个二进制文件。如果您查看生成的 C 文件,这可能会更清楚。利用:

valac a.c b.vala --output demo --save-temps

生成的 C 文件,b.c如下所示:

/* b.c generated by valac 0.43.6.15-63bd-dirty, the Vala compiler
 * generated from b.vala, do not modify */

void my_function (void);
void _vala_main (void);

void
_vala_main (void)
{
        my_function ();
}

int
main (int argc,
      char ** argv)
{
        _vala_main ();
        return 0;
}

没有#include使用 C 预处理器指令。而是my_function在 C 文件本身中声明。可以再次编写接口文件,这次是 C 头文件而不是 VAPI 文件。然后您必须[CCode(cheader_filename = "my_header.h")]在 VAPI 中使用,以便 Vala 生成#include.


推荐阅读