shawind 发表于 2010-1-27 11:05:10

Genie-04-genie,vala,c的胶水

显然genie和vala的混合是最方便的,都是用同一编译系统翻译成c的,要是不能通用,反倒是怪事了。
###在vala里写一个类,然后在genie里调用
a.vala:

public class Test
{
    public int say(string s)
    {
        print(s);
        return 0;
    }
}

b.gs:

init
    var t = new Test()
    t.say("hello")

编译

valac -o test.exe a.vala b.gs

其实Vala和Genie有相当部分是语意一样,只是书面写法不一样。
像上面的那个a.vala就等同于

class Test
    def say(s:string):int
        print(s)
        return 0

当然了,区别还是有的,比如这个例子里,vala里的print要比genie里的print少了个\n号。
反过来,genie里声明,vala调用也是一样的。个人兴趣在Genie上,不说vala。

既然都被翻译成c,也就意味着可以直接用c代码。
Genie里提供了extern关键字来修饰函数或类方法,可以直接调用c文件里的函数。
###方法一:先从c文件开始
a.c:

#include "windows.h"

typedef enum
{
    IntType,
    FloatType
}MyEnum;

typedef struct
{
    const char* s;
    int a;
    float b;
    char t;
}mytest;

void msgbox(mytest t, MyEnum me)
{
    switch(me)
    {
        case IntType:
            sprintf(t.t, "%s:%d", t.s, t.a);
            break;
        case FloatType:
            sprintf(t.t, "%s:%f", t.s, t.b);
            break;
        default:
            break;
    }
    
    MessageBoxA(NULL, &t.t, "MessageBox", 0);
}

b.gs:

enum MyEnum
    IntType
    FloatType


struct mytest
    s:string
    a:int
    b:float
    t:char

def extern msgbox(mt:mytest, me:MyEnum)

init
    mt:mytest = {"Value", 1, 1.0f};
    msgbox(mt, MyEnum.IntType);
    msgbox(mt, MyEnum.FloatType);

是可以修饰如何用来编译成c代码的Attributes。
这里是用说明定义的这个struct,使其和c一样的值类型的方式工作。
Genie里的struct其实就是c里的struct的指针,也就是引用类型。
以后写c文件常记得用struct指针,就不再写了。
用了winapi,自然编译前要先加上mingw32的winapi库。http://sourceforge.net/projects/mingw/files/MinGW%20API%20for%20MS-Windows/

valac -X -mwindows -o test.exe a.c b.gs

这种作法写了两次数据定义,有点麻烦。
当然了,也可以把b.gs里的数据定义部分移出来,单独写在一个gs文件里,方便管理和修改。
其实,完全可以只写一次定义,不过编译却要2-3次。且可以不用为struct写了。

###方法二:先从gs文件开始
先编译上面的去掉这个的b.gs

valac b.gs -C -H b.h

加参数用-C -H a.h输出头文件。(-H参数一定要指定头文件的名字)
再在a.c里包含b.h。试着编译一次:

valac b.gs a.c

一般来说b.h源文件里会有一些“奇怪的东西”报错,只要不是所需要的类型定义,完全可以注释掉出错的行。另外还有一些定义,像enum里的成员等等,编译器会自动为它改名,所以a.c文件也要相应的改动。
ps.如果不是从上面的例子复制来,而是直接写c文件,那么直接用b.h里改好的名字就行。
新的a.c:

#include "b.h"
#include "windows.h"

void msgbox(mytest* t, MyEnum me)
{
    switch(me)
    {
        case MY_ENUM_IntType:
            sprintf(t->t, "%s:%d", t->s, t->a);
            break;
        case MY_ENUM_FloatType:
            sprintf(t->t, "%s:%f", t->s, t->b);
            break;
        default:
            break;
    }
    
    MessageBoxA(NULL, &t->t, "MessageBox", 0);
}

再次

valac b.gs a.c

搞定,收工。

Gneie的基本内容差不多就这么些了吧。除了Genie自己外,库里还有不少的lgpl的东西。gee被Genie默认使用了,那么下面的目标是gtk+。

ps.简单的试了下GTK+,官方的DEMO在我的Win7下,有两个例子莫名其妙的出错,也查不出来是哪里出的问题。再加上GTK+在Win下不是原生的风格,所以还是放弃使用GTK+的打算,反正游戏也用不了那么多的GUI元件,调用c写个窗口创建和消息处理就差不多了。
页: [1]
查看完整版本: Genie-04-genie,vala,c的胶水