我尝试使用Cuhre
库中提供的Cuba
例程。我以前遇到过将静态库链接到Cython
的错误,因此我尝试使用Cuhre
属性创建共享库。为此,我有三个文件:cuhre.c, cuhre.h, and libcuhre.so
(通过编译cuhre.c
创建)。
cuhre.c
有一个例程tryCuhre,它基本上调用古巴图书馆提供的Cuhre路由。为简单起见,它仅适用于2D集成:
double tryCuhre(integrand_t t, void * ud)
{
int comp, nregions, neval, fail;
cubareal integral[NCOMP], error[NCOMP], prob[NCOMP];
Cuhre(2, 1, t, ud, 1,
EPSREL, EPSABS, VERBOSE | LAST,
MINEVAL, MAXEVAL, 13,
STATEFILE, SPIN,
&nregions, &neval, &fail, integral, error, prob);
return (double)integral[0];
}
所有大写字母中的变量(例如MINEVAL和SPIN)都是在编译时预定义的并且是常量。
这是我的cuhre.h
文件,由cuhre.c包含:
#ifndef CUHRE_H_
#define CUHRE_H_
#ifdef __cplusplus
extern "C" {
#endif
typedef double cubareal;
typedef int (*integrand_t)(const int *ndim, const cubareal x[], const int
*ncomp, cubareal f[], void *userdata);
double tryCuhre(integrand_t t, void * ud);
#ifdef __cplusplus
}
#endif
#endif
运行命令集后
gcc -Wall -fPIC -c cuhre.c
gcc -shared -o libcuhre.so cuhre.o
我可以创建共享库libcuhre.so
。到现在为止还挺好。应该注意的是,到目前为止,例程正常工作,即使cuhre.c中的可执行文件正确执行。
我正在尝试使用tryCuhre
文件中的cython
例程(execute.pyx
)。在顶部,我有声明:
cdef extern from "math.h":
double sin(double x)
double cos(double x)
double sqrt(double x)
double atan(double x)
double exp(double x)
double log(double x)
cdef extern from "cuhre.h":
ctypedef double cubareal
ctypedef int (*integrand_t)(const int *ndim, const cubareal x[], const int *ncomp, cubareal f[], void *userdata)
double tryCuhre(integrand_t t, void * ud)
最后,为了编译,我正在使用命令
python setup.py build_ext --inplace
在setup.py上,如下所示:
from distutils.core import setup, Extension
from Cython.Distutils import build_ext
from Cython.Build import cythonize
from distutils.extension import Extension
sourcefiles = ['execute.pyx']
ext_modules = [Extension("execute", sourcefiles, library_dirs =
['~/Documents/project/libcuhre.so'],)]
setup(
name = 'execute',
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules
)
编译文件。但是,每当我尝试声明时
import execute
在python shell中,它引发了错误:
/Documents/project/execute.so: undefined symbol: tryCuhre
我已经四处寻找链接我人工创建的libcuhre.so库的方法,但到目前为止还没有工作。如何解决这个问题?为什么我的程序如何能够从数学库中找到所有方法(sin,cos,exp等),而不是我的libcuhre.so
中的任何方法? (还应注意,所有这些文件都在同一目录~/Documents/project
。)
非常感谢您的帮助!
答案 0 :(得分:0)
依赖的源代码和库需要包含在Extension
中,作为libraries
链接,或源文件进行编译。
library_dirs
仅添加到链接器将搜索库的目录,但不链接任何内容,因此是不够的。
在这种情况下,由于C代码是自构建的并且是单个.c
,因此最简单的方法是将它们一起编译为源代码。这也意味着cuhre.c
将由setuptools本身编译,自动编译目标分发。
from setuptools import setup, Extension
from Cython.Distutils import build_ext
from Cython.Build import cythonize
sourcefiles = ['execute.pyx', 'cuhre.c']
ext_modules = [Extension("execute", sourcefiles,
include_dirs=['.'],
depends='cuhre.h',
)]
setup(
name='execute',
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules
)
代码也更改为使用setuptools
,distutils
已弃用,现在已成为setuptools的一部分。