2010-03-23 3 views
11

Vala를 사용하여 기존 GLib 기반 C 프로젝트를 해킹하고 싶습니다.Vala vapi 파일 설명서

기본적으로 내가하고있는 일은 빌드 프로세스의 시작 부분에 valac을 사용하여 .vala 파일에서 .c 및 .h 파일을 생성 한 다음 생성 된 파일을 .c 또는 .h 파일.

이것은 아마도 최선의 방법은 아니지만 대부분 제대로 작동하는 것으로 보입니다.

제 문제는 Vala 코드에서 기존 C 코드에 액세스하는 데 어려움이 있습니다. 이 작업을 수행하는 쉬운 방법이 있습니까?

나는 내 자신의 .vapi 파일을 만들려고했는데 (나는 vala와 함께 제공되는 도구와 관련하여 운이 없었습니다.), 그러나 이것을 작성하는 방법에 관해서는 알맞은 문서를 찾을 수 없습니다.

존재합니까? 기존 C 코드를 호출하려면이 파일 중 하나가 필요합니까?

답변

15

예, C 함수를 호출하려면 바인딩을 작성해야합니다. 이 과정은 http://live.gnome.org/Vala/Tutorial#Binding_Libraries_with_VAPI_Files에 설명되어 있지만 GObject없이 작성된 사용자 지정 함수 나 라이브러리에는 직접 적용되지 않습니다. 비 -GObject 라이브러리에 대한 복잡한 바인딩이있는 경우 #vala IRC 채널의 도움이 필요할 것입니다.

그러나 대부분의 경우, 우리는 단순한 vapi 파일을 사용하여 효율성에 대한 이유로 또는 평범한 C로 작성된 일부 기능을 바인드했습니다. (프로젝트와 연결된이 .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

#include <glib-object.h> 
char* my_func_foo(int bar, GObject* o) 

example.vala : 그리고 이것은 대부분의 사람들이 할 수있는 방법입니다 valac로 컴파일 할 때, 디렉토리 보라를 제공하기 위해 --vapidir=를 사용

using MyFunc; 

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

수 myfunc.vapi의 양이온. 빌드 시스템에 따라, 모든 것을 연결하기 위해 valac 또는 gcc CFLAGS에 추가 인수를 전달해야 할 수도 있습니다.

+0

고마워요! 내가 가지고있는 한가지 문제점은 myfunc.vapi에 헤더 파일을 지정할 때, valac의 .c 출력에 #include ""이 쓰일 때 실제로 원하는 것은 #include "myfunc.h"입니다. 어떤 생각이 어떻게 해결할 수 있습니까? 해결할 수 있습니까? – Jordan

+0

파일이 시스템 include에 설치되어 있지 않으면 경로를 -I로 제공하면 프로젝트 디렉토리에 파일이 열립니다 (예 : -I $ (topsrc_dir))/libfoo) – elmarco

1

elmarco의 답변에 추가 할 수있는 것은 extern 키워드뿐입니다. 패키지 중 하나 또는 표준 C/Posix 라이브러리에서 이미 사용 가능한 단일 C 함수에 액세스하려는 경우이 방법으로 쉽게 액세스 할 수 있습니다.

-1

c에서 vala 코드에 액세스하는 것이 더 쉬울 것입니다. 그냥 C로 컴파일하면됩니다.

1

C로 작성된 GLib 기반 라이브러리의 경우 C 소스에서 Vala/Bindings의 gir 파일을 생성하려고 할 수 있습니다.

수동으로 수행하는 것도 문제가되지 않습니다. 문자열을 취하는 do_something이라는 메서드로 C에서 SomelibClass1을 정의하는 라이브러리가 있다고 가정합니다. 헤더 파일의 이름은 "somelib.h"입니다. 그러면 해당 vapi는 다음과 같이 간단합니다.

somelib.VAPI : 비 입심 라이브러리에 대한 쓰기 vapis에 대한

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

문서는 여기에서 찾을 수 있습니다 : Vala/LegacyBindings

이 실제로 정말 간단합니다.

[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 폐기

발라 개체는 방법 첫번째 파라미터라고 가정 특성 posix.vapi 발췌문을하자. 이 방법으로 대략 객체 지향적 인 c-construct를 묶는 것이 가능합니다. 컴팩트 클래스의 free_method는 객체가 참조 해제 될 때 호출됩니다.

등 메서드, 클래스, 구조체의 CCODE (CNAME) -attribute는 C.에있을 것 같은 그것의 이름이어야

이 주제에 대한 더 많은있다

하지만,이 일반적인 개요를 제공해야합니다.

+0

이 링크가 질문에 대답 할 수도 있지만 여기에 대답의 핵심 부분을 포함하고 참조 용 링크를 제공하는 것이 좋습니다. 링크 된 페이지가 변경되면 링크 전용 답변이 유효하지 않게 될 수 있습니다. –

+0

힌트를 주셔서 감사합니다. 나는 내 대답을 편집했다. – Richard