如何将scipy.weave.inline与外部C库一起使用?
我正在尝试理解weave.inline这个工具,用来在我的Python程序中嵌入C代码。下面的代码简单地将Numpy数组中的所有元素都乘以2。
inl.py
import numpy
import scipy.weave
a = numpy.array([1.0, 2.0, 3.0])
N = a.shape[0]
print a
code = \
"""
int i;
for(i = 0; i < N; i++)
{
a[i] = a[i] * 2;
}
"""
scipy.weave.inline(code, ['a','N'])
print a
接着,我想把一些函数从内嵌代码转移到外部库里。比如说,简单的乘以2的操作。所以我创建了两个文件:
mult.c
#include "mult.h"
float mult(float n)
{
return n * 2;
}
mult.h
float inc(float n);
现在我想在我的内嵌代码中使用mult这个函数。但是我不知道怎么把我的C文件和Python的内嵌代码连接起来。我试着把C文件编译成共享库,并在weave中把它们作为头文件和库传递,但都没有成功。有没有什么建议?
2 个回答
把 mult.c 和 mult.h 的源代码放到一个叫 extra_code 的字符串对象里,然后在你的 .weave 调用中加上以下这一行
support_code=extra_code,
还有一个选项可以像下面这样包含标准库:
headers = ["<math.h>"]
祝你玩得开心
我成功地通过weave.inline()在R中调用了数学函数,操作是在Ubuntu Linux系统下进行的。
首先,你需要把你的C函数编译成一个共享库。在我的情况下,我从CRAN下载了一个最新版本的R,然后执行了
./configure --enable-R-static-lib --enable-static --with-readline=no
cd src/nmath/standalone/
make
现在你应该会有一个叫做 libRmath.so
的文件。如果 libpath
是一个包含 libRmath.so
文件的目录的字符串,你可以这样做
code = 'return_val = pbinom(100, 20000, 100./20000., 0, 1);'
support_code = 'extern "C" double pbinom(double x, double n, double p, int lower_tail, int log_p);'
weave.inline(code, support_code=support_code,
library_dirs=[libpath], libraries=["Rmath"], runtime_library_dirs=[libpath])
注意几点。头文件的声明要放在 support_code
中,而不是 code
(我也不知道为什么),而且它们必须以 extern "C"
开头,因为这是C代码,不是C++(这是标准做法)。理论上可以直接包含头文件,而不是使用 support_code
(可以查看weave.inline的文档),但我还没有尝试过。库的名字是 Rmath
,但共享库文件是 libRmath.so
,这是Unix的常规命名方式。库的路径需要指定两次,一次用于链接,一次用于执行。
希望这些信息对你有帮助!