如何将scipy.weave.inline与外部C库一起使用?

7 投票
2 回答
4658 浏览
提问于 2025-04-16 07:31

我正在尝试理解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 个回答

1

把 mult.c 和 mult.h 的源代码放到一个叫 extra_code 的字符串对象里,然后在你的 .weave 调用中加上以下这一行

support_code=extra_code,

还有一个选项可以像下面这样包含标准库:

headers = ["<math.h>"]

祝你玩得开心

6

我成功地通过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的常规命名方式。库的路径需要指定两次,一次用于链接,一次用于执行。

希望这些信息对你有帮助!

撰写回答