【问题标题】:Vala vapi files documentationVala vapi 文件文档
【发布时间】:2011-01-30 14:22:33
【问题描述】:

我想使用 Vala 破解现有的基于 GLib 的 C 项目。

基本上我正在做的是,在我的构建过程开始时,使用 valac 从我的 .vala 文件生成 .c 和 .h 文件,然后按照我的任何 .c 或 .c 文件的方式编译生成的文件。 h 文件。

这可能不是最好的方法,但在大多数情况下似乎工作正常。

我的问题是我很难从 Vala 代码中访问现有的 C 代码。是否有捷径可寻?

我尝试过编写自己的 .vapi 文件(我没有使用 vala 附带的工具),但我找不到任何关于如何编写这些文件的体面文档。

有吗?我需要这些文件之一来调用现有的 C 代码吗?

【问题讨论】:

    标签: c glib vala vapi


    【解决方案1】:

    是的,要调用 C 函数,您需要为其编写绑定。该过程在http://live.gnome.org/Vala/Tutorial#Binding_Libraries_with_VAPI_Files 中进行了描述,但是,这并不直接适用于没有 GObject 编写的自定义函数或库。如果您对非 GObject 库有复杂的绑定,您可能需要#vala IRC 频道的帮助。

    然而,大多数时候,我们使用简单的 vapi 文件来绑定一些 autoconf 定义或一些用纯 C 编写的函数,出于效率原因或损坏的 vala 或任何其他原因。这是大多数人的做法:

    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 传递额外的参数,以便将所有内容链接在一起。

    【讨论】:

    • 谢谢!我遇到的一个问题是,当我在 myfunc.vapi 中指定头文件时,valac 的 .c 输出会写入 #include ,而我真正想要的是 #include "myfunc.h"。知道如何解决这个问题吗?能解决吗?
    • 这应该没什么大不了的,只要该文件没有安装在您的系统包含中,它将在您的项目目录中打开,如果您提供带有 -I.. 的路径(示例:-I$(topsrc_dir)/libfoo)
    【解决方案2】:

    我要对 elmarco 的回答做的唯一补充是 extern 关键字。如果您尝试访问您的某个包或标准 C/Posix 库中已经提供的单个 C 函数,您可以通过这种方式轻松访问它。

    【讨论】:

      【解决方案3】:

      对于用 C 编写的基于 GLib 的库,您可以尝试从 C 源代码生成 gir 文件:Vala/Bindings

      手动操作也没问题。假设您有一个库,该库在 C 中定义 SomelibClass1,其中包含一个名为 do_something 的方法,该方法接受一个字符串。 头文件的名称是“somelib.h”。那么对应的vapi就简单如下:

      somelib.vapi:

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

      为非 GLib 库编写 vapis 的文档可以在这里找到: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-Function:

      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 中一样。

      这个主题还有很多内容,但这应该会给你一个大致的概述。

      【讨论】:

        【解决方案4】:

        从 c 访问您的 vala 代码可能会更容易。因为你所要做的就是编译成 C。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-06-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多