狠狠撸

狠狠撸Share a Scribd company logo
Py + GI
?高效 C 庫整合?方案
Derek 呆
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
●?Derek 呆
○?dailidu@linuxdeepin.com
○?daiderek@gmail.com
●?來?自 Linux Deepin
●?慣 C
●?愛 Python
●?搞 BASH
●?編 Linux System Program
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
Python <= (Binding) => C
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
?手寫, 費時, 易出錯, 重複造輪
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
想?用?工具代勞?
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
試試 PyGObject
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
基於 GObject Introspection (GI)
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
與 Python 間只有少量整合代碼
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
?自源代碼?生成 Type Library
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
包含 Version, Function Signature,
Type Information, ...
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
可於多語?言間共?用
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
Runtime 時配合 libffi 進?行調?用
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
易於將成果推送到 Upstream
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
準備?工作
$ apt-get install build-essential 
gobject-introspection 
python-gobject 
libglib2.0-dev 
gtk-doc-tools
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
例 1
/* mylib.h */
#ifndef __MYLIB_H_
#define __MYLIB_H_
void hello();
#endif /* __MYLIB_H_ */
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
例 1
/* mylib.c */
#include "mylib.h"
#include <stdio.h>
void hello()
{
printf("hellon");
}
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
例 1
$ gcc -o libmylib.so -share …
$ g-ir-scanner -o MyLib-1.0.gir 
-lmylib 
-L. 
mylib.h
…
$ g-ir-compiler MyLib-1.0.gir >MyLib-1.0.typelib
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
例 1
...
<namespace name="MyLib"
version="1.0"
shared-library="libmylib.so"
c:identifier-prefixes="MyLib"
c:symbol-prefixes="my_lib">
<function name="hello" c:identifier="hello">
<return-value transfer-ownership="none">
<type name="none" c:type="void"/>
</return-value>
</function>
</namespace>
...
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
例 1
$ python -c 'from gi.repository import
MyLib; MyLib.hello()'
hello
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
資源管理是 Binding 開發?一?大重點
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
否則 Resource Leaking, Double Free,
Invalid FD, Bus Error, Segfault...
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
例 2
/* mylib.h */
#ifndef __MYLIB_H_
#define __MYLIB_H_
const char * hello3();
char * hello2();
#endif /* __MYLIB_H_ */
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
例 2
/* mylib.c */
#include "mylib.h"
#include <stdio.h>
#include <string.h>
const char * hello3()
{
return "hello";
}
char * hello2()
{
return strdup("hello");
}
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
例 2
...
<function name="hello2" c:identifier="hello2">
<return-value transfer-ownership="full">
<type name="utf8" c:type="char*"/>
</return-value>
</function>
<function name="hello3" c:identifier="hello3">
<return-value transfer-ownership="none">
<type name="utf8" c:type="const char*"/>
</return-value>
</function>
...
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
例 2
$ python -c 'from gi.repository import
MyLib; print MyLib.hello2(); print
MyLib.hello3()'
hello
hello
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
GI 有默認資源管理策略
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
但可通過 Annotation 改變
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
例 3
#ifndef __MYLIB_H_
#define __MYLIB_H_
/**
* hello4:
* Returns: (transfer full):
*/
const char * hello4();
#endif /* __MYLIB_H_ */
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
例 3
#include "mylib.h"
#include <stdio.h>
const char * hello4()
{
return "hello";
}
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
例 3
python -c 'from gi.repository import MyLib;
print MyLib.hello4()'
*** Error in `python': munmap_chunk():
invalid pointer: 0x00007f4503efd65d ***
Aborted
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
Out 參數能處理嗎?
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
例 4
/**
* hello5:
*
* @msg: (out callee-allocates):
*/
void hello5(char **msg);
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
例 4
void hello5(char **msg)
{
*msg = strdup("hello");
}
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
例 4
$ python -c 'from gi.repository import
MyLib; print MyLib.hello5()'
hello
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
Out 參數會以 Return Value呈現
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
Struct ?又如何?
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
?一個 Type 需加上 4 個 Functions
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
基本也可以?工具產?生
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
例 5
#include <glib-object.h>
#define TYPE_MY_OBJ (my_obj_get_type())
typedef struct _MyObj MyObj;
MyObj my_obj_new();
GType my_obj_get_type();
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
例 5
struct _MyObj
{
int v;
};
MyObj * my_obj_new()
{
return malloc(sizeof(MyObj));
}
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
例 5
MyObj * _my_obj_copy(MyObj *self)
{
MyObj *new_self = my_obj_new();
*new_self = *self;
return new_self;
}
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
例 5
void _my_obj_free(MyObj *self)
{
free(self);
}
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
例 5
GType my_obj_get_type()
{
static GType type = 0;
if(! type) {
type = g_boxed_type_register_static(
"MyObj",
(GBoxedCopyFunc) _my_obj_copy,
(GBoxedFreeFunc) _my_obj_free);
}
return type;
}
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
例 5
$ python
>>> from gi.repository import MyLib
>>> o = MyLib.MyObj()
>>> o
<MyObj at 0x27d39c0>
>>> o.copy()
<MyObj at 0x2a7b7e0>
>>> o = None
>>>
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
還有?支持不了的類型嗎?
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
Variadic Function
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
?一些資源
●? 完整內容
●? git repository
●? Annotation 參考
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!
廣告時間
●? Linux Deepin, 專注桌?面體驗的桌?面系統
●? 深之度公司?文化
○? 低調, 做好實事
○? ?支持開源?人, 做想做的開源事
○? 週五 Hacking Day 讓你 Hack ?自我
●? 總部位於武漢
●? 提供遠程?工作機會等你來挑戰
北京/上海/??广州 0xFF Life's pathetic, go Pythonic!

More Related Content

Py + gi 高效 c 庫整合方案