Python cffi 学习笔记2(API level,out-
2016-08-23 本文已影响0人
李二狗2000
环境
ubuntu16.04
python3.5.1+
cffi 1.7.0
gcc 5.4.0
例子(API level, out-of-line)
# file "example_build.py"
# Note:我们和章节1中的例子一样实例化了'cffi.FFI',
# 但是这次实例名字为'ffibuilder',而不是'ffi';
# 这样可以避免混淆。
import FFI
ffibuilder = FFI()
ffibuilder.set_source("_example",
""" // 传递给C编译器
#include <sys/types.h>
#include <pwd.h>
""",
libraries=[])
ffibuilder.cdef(
""" // man page或者头文件里面复制的定义
struct passwd { char *pw_name; ...; // 三个点 };
struct passwd *getpwuid(int uid);
""")
if __name__ == "__main__":
ffibuilder.compile(verbose=True)
运行一次example_build.py
$python example_build.py
generating ./_example.c
running build_ext
building '_example' extension
x86_64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -I/usr/include/python3.5m -I/home/wang/venv/include/python3.5m -c _example.c -o ./_example.o
x86_64-linux-gnu-gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-Bsymbolic-functions -Wl,-z,relro -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 ./_example.o -o ./_example.cpython-35m-x86_64-linux-gnu.so
# 生成三个文件:_example.c,
# _example.o,
# _example.cpython-35m-x86_64_linux-gnu.so
CFFI根据set_source()
第二个参数是不是None
来选择生成Python module(.pyd)还是C module(.so)。
然后在主程序,这样写:
# file "example.py"
from _example import ffi, lib
p = lib.getpwuid(0)
print(ffi.string(p.pw_name))
主程序运行结果:
# 输出
$python example.py
b'root'
大家会发现,在
pwd.h
中定义的struct passwd
是这样的:
struct passwd
{
char * pw_name; /* Username, POSIX.1 /
char * pw_passwd; / Password /
__uid_t pw_uid; / User ID, POSIX.1 /
__gid_t pw_gid; / Group ID, POSIX.1 /
char * pw_gecos; / Real Name or Comment field /
char * pw_dir; / Home directory, POSIX.1 /
char * pw_shell; / Shell Program, POSIX.1 */
char *pw_class;
time_t pw_change;
time_t pw_expire;
};
>而我们定义的是
>```python
ffibuilder.cdef(
""" // man page或者头文件里面复制的定义
struct passwd { char *pw_name; ...; // 三个点 };
struct passwd *getpwuid(int uid);
""")
未完待续。。。