我想使用Vala修改一个现有的基于GLib的C项目。
基本上,我所做的是,在构建过程的开始,使用valac从我的.vala文件生成.c和.h文件,然后像编译任何.c或.h文件一样编译生成的文件。
这可能不是最好的方法,但似乎在很大程度上工作得很好。
我的问题是,我很难从我的Vala代码中访问我现有的C代码。有什么简单的方法可以做到这一点吗?
我已经尝试过编写自己的.vapi文件(我没有使用vala附带的工具),但是我找不到任何关于如何编写这些文件的合适文档。
真的存在吗?我是否需要其中一个文件来调用现有的C代码?
发布于 2010-03-25 07:12:46
是的,要调用一个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);
}H(以及与您的项目链接的.c中的相应实现)
#include <glib-object.h>
char* my_func_foo(int bar, GObject* o)example.vala可能是
using MyFunc;
void main() {
baz = foo(42);
}在使用myfunc.vapi进行编译时,请使用--vapidir=提供valac的目录位置。根据您的构建系统,您可能需要将额外的参数传递给valac或gcc CFLAGS,以便将所有内容链接在一起。
发布于 2010-11-03 08:12:19
我对elmarco的答案唯一的补充就是extern关键字。如果您正在尝试访问某个包或标准C/Posix库中已有的单个C函数,则可以通过这种方式轻松地访问它。
发布于 2014-04-13 17:09:28
对于用C编写的基于GLib的库,您可以尝试从C源生成gir文件:Vala/Bindings。
手动操作也不成问题。假设你有一个用C语言定义SomelibClass1的库,它有一个名为do_something的方法,它接受一个字符串。头文件的名称是“The elib.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函数:
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中一样。
这个主题还有更多的内容,但这应该会给你一个大致的概述。
https://stackoverflow.com/questions/2496656
复制相似问题