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);
    """)

未完待续。。。

上一篇下一篇

猜你喜欢

热点阅读