标签: python-cffi

加载dll时Python CFFI模块失败:OSError 0x7e

我在Windows 7(64位)下运行Python 3.3(Anaconda发行版)。我试图安装Weasyprint应用程序/库,它具有许多依赖性,包括CFFI,我必须从源代码进行编译,因为在二进制发行版中没有兼容的版本。

当我运行weasyprint时,它会在导入加载过程中阻塞,特别是当它调用CFFI以便为开罗加载GTK +库dll时。我得到的错误如下:

$ weasyprint
Traceback (most recent call last):
  File "c:\anaconda\envs\py33\lib\site-packages\cffi-0.8-py3.3-win-amd64.egg\cffi\api.py", line 399, in _make_ffi_library
    backendlib = backend.load_library(name, flags)
OSError: cannot load library libcairo-2.dll: error 0x7e

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Anaconda\envs\py33\Scripts\weasyprint-script.py", line 9, in <module>
    load_entry_point('WeasyPrint==0.20', 'console_scripts', 'weasyprint')()
  File "C:\Anaconda\envs\py33\lib\site-packages\pkg_resources.py", line 343, in load_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "C:\Anaconda\envs\py33\lib\site-packages\pkg_resources.py", line 2355, in load_entry_point
    return ep.load()
  File "C:\Anaconda\envs\py33\lib\site-packages\pkg_resources.py", line 2061, in load
    entry = __import__(self.module_name, globals(),globals(), ['__name__']) …
Run Code Online (Sandbox Code Playgroud)

python windows dll python-cffi

5
推荐指数
1
解决办法
4008
查看次数

Python CFFI将结构转换为字典

有一种方法用字典初始化结构:

fooData= {'y': 1, 'x': 2}
fooStruct = ffi.new("foo_t*", fooData)
fooBuffer = ffi.buffer(fooStruct)
Run Code Online (Sandbox Code Playgroud)

是否有一些准备好的功能来进行转换?

fooStruct = ffi.new("foo_t*")
(ffi.buffer(fooStruct))[:] = fooBuffer
fooData= convert_to_python( fooStruct[0] )    
Run Code Online (Sandbox Code Playgroud)

我必须自己使用ffi.typeof("foo_t").字段吗?

到目前为止,我想出了这个代码:

def __convert_struct_field( s, fields ):
    for field,fieldtype in fields:
        if fieldtype.type.kind == 'primitive':
            yield (field,getattr( s, field ))
        else:
            yield (field, convert_to_python( getattr( s, field ) ))

def convert_to_python(s):
    type=ffi.typeof(s)
    if type.kind == 'struct':
        return dict(__convert_struct_field( s, type.fields ) )
    elif type.kind == 'array':
        if type.item.kind == 'primitive':
            return [ s[i] for i in …
Run Code Online (Sandbox Code Playgroud)

python python-cffi

5
推荐指数
1
解决办法
1255
查看次数

如何在开发期间构建Python CFFI模块?

在开发过程中构建CFFI模块的最佳实践是什么?

现在我正在使用Makefile:

mylib/_ffi.so: my_lib/build_ffi.py
    python $<
Run Code Online (Sandbox Code Playgroud)

然后测试我可以使用:

$ make && python test.py
Run Code Online (Sandbox Code Playgroud)

但这似乎不是最理想的.在开发过程中是否有更好的方法来构建CFFI模块?

python python-cffi

5
推荐指数
1
解决办法
415
查看次数

为CFFI安装Microsoft Visual C++ 14.0的方法是什么,它占用最少的硬盘空间?

我想编写使用的Python软件CFFI.CFFI本身抛出错误:

distutils.errors.DistutilsPlatformError: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": http://landinghub.visualstudio.com/visual-cpp-build-tools
Run Code Online (Sandbox Code Playgroud)

该页面上有多个下载.我不想从Microsoft Visual C++ Build Tools安装数GB的数据.我安装CFFI工作的最低要求是多少?

c++ python python-cffi microsoft-visual-c++

5
推荐指数
0
解决办法
575
查看次数

向 cffi 编译过程添加标志

我使用 cffi 模块来包装简单的 C 代码。问题是,我需要添加一个标志来使其编译(std=c99)。目前我有类似的东西:

from cffi import FFI
ffibuilder = FFI()
with open("test.c", 'r') as f:
    ffibuilder.set_source("mymodule", f.read()) 
with open("test.h", 'r') as f:
    ffibuilder.cdef(f.read())
if __name__ == "__main__":
    ffibuilder.compile(verbose=True)
Run Code Online (Sandbox Code Playgroud)

问题是,cffi 自己调用 gcc,我想将 std=c99 添加到它调用 gcc 的标志中。我缺少任何参数吗?

(注意:我可以更改 gcc 命令本身或运行 cffi 自己使用的 gcc 命令,我想知道我是否缺少一些正确的方法来执行此操作)

python pypy python-cffi

4
推荐指数
1
解决办法
2152
查看次数

CFFI:TypeError:ctype'char []'的初始化程序必须是字节或列表或元组,而不是str

使用用于PythonCFFI库,我试图将Python字符串哄骗到char *中,以便将其传递给接受char *的C函数。我似乎无法弄清楚什么是正确的咒语。

考虑以下示例:

>>> from cffi import FFI
>>> ffi = FFI()
>>> ffi.new("char[]", "bob")
Run Code Online (Sandbox Code Playgroud)

结果是:

TypeError: initializer for ctype 'char[]' must be a bytes or list or tuple, not str
Run Code Online (Sandbox Code Playgroud)

以下内容也不起作用:

>>> ffi.new("char*", "bob")
Run Code Online (Sandbox Code Playgroud)

它说:

TypeError: initializer for ctype 'char' must be a bytes of length 1, not str
Run Code Online (Sandbox Code Playgroud)

python ffi python-cffi

4
推荐指数
1
解决办法
3186
查看次数

在Python中通过ctypes调用ac函数是否在C代码执行期间释放GIL

我想从 python 调用一些 c 函数来提高代码的性能。但我无法在网上找到当我使用 ctypes 库调用 C 函数时 GIL 是否被释放。举个简单的例子:

from ctypes import *
fun = cdll.LoadLibrary("libc.so.6")
fun.sleep.argtypes = [c_uint]
fun.sleep(c_uint(5))
Run Code Online (Sandbox Code Playgroud)

GIL 是否在调用期间被释放fun.sleep

python ctypes gil python-cffi

4
推荐指数
1
解决办法
1228
查看次数

我是否需要释放通过CFFI调用的C函数返回的内存?

我有一个示例代码,该示例代码具有一个text()返回新分配的字符串的函数:

ffi_test = FFI()
ffi_test.set_source('_test', '''
char* test() { return strdup("hello world"); }
''')
ffi_test.cdef('''
char* test();
void free(void *);
''')
ffi_test.compile(verbose=True)
Run Code Online (Sandbox Code Playgroud)

这很好用:

In [1]: from _test import ffi, lib
In [2]: x = lib.test()
In [3]: ffi.string(x)
Out[3]: b'hello world'
In [4]: lib.free(x)
Run Code Online (Sandbox Code Playgroud)

但是,我在文档中找不到任何内容,是否我真的需要手动free()返回的字符串,如果CFFI在返回到Python代码后立即拥有该指针的所有权。

另外,如果我确实需要手动执行free()此操作,是否需要free()cdef中公开它?CFFI是否为此提供了更好的方法?

c python free memory-management python-cffi

3
推荐指数
1
解决办法
731
查看次数

如何使用cffi嵌入在C语言中返回字符串的Python函数?

我正在尝试使用PyPy和cffi将Python函数嵌入C中。我正在遵循PyPy文档中的本指南

问题是,我发现的所有示例都在ints上操作,并且我的函数采用字符串并返回字符串。我似乎无法弄清楚如何将此函数嵌入C中,因为C似乎并没有真正的字符串,而是使用char数组。

这是我尝试过的:

# interface.py

import cffi

ffi = cffi.FFI()
ffi.cdef('''
struct API {
    char (*generate_cool_page)(char url[]);
};
''')

...


@ffi.callback("char[] (char[])")
def generate_cool_page(url):
    # do some processing with BS4
    return str(soup)

def fill_api(ptr):
    global api 
    api = ffi.cast("struct API*", ptr)
    api.generate_cool_page = generate_cool_page
Run Code Online (Sandbox Code Playgroud)

-

// c_tests.c

#include "PyPy.h"
#include <stdio.h>
#include <stdlib.h>

struct API {
    char (*generate_cool_page)(char url[]);
};

struct API api;   /* global var */

int initialize_api(void)
{
    static char source[] =
        "import sys; sys.path.insert(0, '.'); …
Run Code Online (Sandbox Code Playgroud)

c python string pypy python-cffi

2
推荐指数
1
解决办法
832
查看次数

有没有办法从Python调用Rust的异步接口?

我将reqwestrust 的一些函数包装到req.lib文件中,并使用cffi. 然而reqwest::blocking::Client强迫我在 python 中使用多线程。我发现reqwest可以在 Rust 中以异步模式调用。我想知道有没有办法实现req.lib异步?即使是半异步对我来说也可以。

例如,当前存根签名是:

#[no_mangle]
pub extern "C" fn urlopen(url: *const c_char) -> *mut c_char
Run Code Online (Sandbox Code Playgroud)

我可以写一些类似的东西:

#[no_mangle]
pub extern "C" fn urlopen(url: *const c_char) -> u64  // return request unique id

#[no_mangle]
pub extern "C" fn is_finished(req_id: u64) -> bool  // whether given request is done

#[no_mangle]
pub extern "C" fn fetch_result(req_id: u64) -> *mut c_char  // fetch response
Run Code Online (Sandbox Code Playgroud)

因此cffi调用不再锁定主线程。我可以使用单线程来调用多个请求。欢迎任何建议或最佳实践。

python asynchronous rust python-cffi

2
推荐指数
1
解决办法
1091
查看次数

定义结构时python cffi解析错误

我试图用来python-cffi包装C代码.以下example_build.py显示了包装lstat()调用的尝试:

import cffi

ffi = cffi.FFI()
ffi.set_source("_cstat",
        """
        #include <sys/types.h>
        #include <sys/stat.h>
        #include <unistd.h>
        """,
        libraries=[])

ffi.cdef("""
        struct stat {
            mode_t  st_mode;
            off_t   st_size;
            ...;
        };
        int lstat(const char *path, struct stat *buf);
""")


if __name__ == '__main__':
    ffi.compile()
Run Code Online (Sandbox Code Playgroud)

当编译时python example_build.py会抱怨解析错误mode_t st_mode.

cffi.api.CDefError: cannot parse "mode_t  st_mode;"
:4:13: before: mode_t
Run Code Online (Sandbox Code Playgroud)

手册中给出的类似示例没有任何问题.我错过了什么?TIA.

python python-cffi

1
推荐指数
1
解决办法
2040
查看次数