vala
语言编写gtk
界面程序非常简单方便,而且它编译时会翻译成c
语言,所以可以方便的调用go
编译器生成的c-archive
。
一、把 C 头文件翻译称vala
可用的 vapi
文件
要用vala
调用go
导出的函数,就先要把 C
头文件翻译称vala
可用的 vapi
文件。例如我的一个go
程序用go build -buildmode=c-archive
生成了两个文件:libmychat.a
、libmychat.h
,头文件提供的函数如下:
extern GoInt GetMsg(char** p0, char** p1);extern void ChatInit(int p0);extern GoInt SetIRCServer(char* p0);extern GoInt SetNick(char* p0);extern GoInt SetRoom(char* p0, char** p1);extern GoInt SetKey(char* p0);extern char* GetHead(int p0);extern void Quit();extern void Say(char* p0, char* p1);extern GoInt GetStep();
翻译成对应的mychat.vapi
文件内容如下:
[CCode (cheader_filename="libmychat.h")]public static int GetMsg(out string p0, out string p1);public static void ChatInit(int p0);public static int SetIRCServer(string p0);public static int SetNick(string p0);public static int SetRoom(string p0, out string p1);public static int SetKey(string p0);public static string GetHead(int p0);public static void Quit();public static void Say(string p0, string p1);public static int GetStep();
对应关系非常简单吧。
二、如何实现go
程序回调vala
程序的问题
上面已经解决打了vala
调用go
程序导出的函数的问题,但是还不够,我们在处理外部消息的时候经常需要让go
线程回调vala
以便显示信息。要直接实现这个功能可能很复杂,但是转个弯,让go
程序内部把信息发送到一个channel
,导出一个专门读取和处理这个channel
的阻塞型函数,而vala
程序可以用一个独立线程循环调用这个函数,并处理接收到的信息。问题就这么简单的解决了。
下面就是一个示例:
//go 代码,使用 cgo 直接从参数返回2个 C 字符串//export GetMsgfunc GetMsg(from, msg **C.char) int { m, ok := <-chan1 var ret int if ok { *from = C.CString(m.From) *msg = C.CString(m.Msg) ret = 1 } else { *from = nil *msg = nil ret = 0 } return ret }//vala 代码//循环读取消息的函数public int loop_msgs(){ int ret; while(true){ string from,msg; ret = GetMsg(out from, out msg); //处理和显示 ...... } }//在线程中调用 loop_msgsvar thread = new Thread<int>.try ("irc1", this.loop_msgs);
三、如何编译
展示一个Makefile
,大家就很容易理解了。
mimichat:chatui.vala mychat.vapi valac -o mimichat --pkg gtk+-3.0 --thread -X -I. -X -L. -X -lmychat chatui.vala
作者:从火星来
链接:https://www.jianshu.com/p/d7f1e003ff20
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦