Cython:动态" cdef extern from xxx"

时间:2016-05-17 22:22:20

标签: python numpy cython

我试图直接访问numpy函数random/randomkit.h,以便在具有cython的多线程应用程序中使用随机生成器(即没有gil)。

为此,我尝试使用以下代码从numpy文件夹中访问头文件:

import os
import numpy

str_rkdir = os.path.dirname(os.path.abspath(numpy.__file__))
str_randomkit_h = str_rkdir + "/random/randomkit.h"

cdef extern from str_randomkit_h:
   ctypedef struct rk_state
   cdef unsigned long rk_random(rk_state * state) nogil
   cdef signed long rk_gauss(rk_state * state) nogil
   cdef void rk_seed(unsigned long seed, rk_state * state) nogil

然而,这不适用于pyximport,因为cython抱怨str_randomkit_h字符串(我猜它在编译之前没有解释python代码)...有一种简单的方法在这附近?

作为一种肮脏的解决方法,我在cython编译之前动态生成.pxd,但这并不是真的很好,所以我想知道是否有更好的方法来实现它。

1 个答案:

答案 0 :(得分:1)

动态地,你不能以这种方式工作,因为正如你所说,没有解释,只有编译。 DEF因为可以在预处理阶段使用的功能有限而无法提供帮助。我不相信还有其他一些偷偷摸摸的方法可以做到这一点;您需要使用pyximportsetup.py脚本。

使用pyximport,您可以为install函数提供适当的参数。包含包含文件的目录可以在setup_args字典中以键'include_dirs'的形式给出:

>>> from numpy import random as rnd    
>>> from pyximport import install
>>> install(setup_args={'include_dirs':rnd.__path__[0] + '/'})

当然,这样做意味着您还要更改.pxd文件以将标题名称作为字符串文字提供:

cdef extern from "randomkit.h": 
    ...

或者,using a setup script非常简单。再次,您只需在以某种方式计算它们之后提供include_dirs