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

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

6

我已经成功地通过weave.inline()代码(在Ubuntu Linux下)调用了数学函数从R中进行翻译。

首先,将您的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惯例。并且需要两次指定库的路径,一次用于链接,一次用于执行。
希望这有所帮助!

1
将mult.c和mult.h的源代码放入名为extra_code的字符串对象中,然后在.weave调用中添加以下行。
support_code=extra_code,

还有一种选择是按照以下方式包含标准库:

headers = ["<math.h>"]

享受


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接