可以使用F2PY封装共享库中的函数吗?

17 投票
1 回答
758 浏览
提问于 2025-04-18 06:07

我正在开发一个需要使用LAPACK Fortran库中的dgtsv子程序的Python绑定的包。目前,我把Fortran源文件dgtsv.f和我的Python代码放在一起,并使用numpy.distutils来自动将它包装并编译成一个可以从Python调用的共享库_gtsv.so

现在我的setup.py文件大致是这样的:

from numpy.distutils.core import setup, Extension, build_ext
import os


fortran_sources = ["dgtsv.f"]
gtsv = Extension(
    name="pyfnnd._gtsv",
    sources=[os.path.join("pyfnnd", "LAPACK", ff) for ff in fortran_sources],
    extra_link_args=['-llapack']
)

setup(
    name='pyfnnd',
    py_modules=['_fnndeconv', 'demo', '_tridiag_solvers'],
    cmdclass={'build_ext': build_ext.build_ext},
    ext_modules=[gtsv],
)

需要注意的是,为了真正使用_gtsv.so,我还需要链接一个已经存在的LAPACK共享库(extra_link_args=['-llapack'])。因为这个库应该已经包含了dgtsv子程序,所以我觉得直接在现有的共享库中包装这个函数会更简洁,而不是必须分发实际的Fortran源代码。

不过,我从来没有见过使用F2PY来包装属于共享库的函数的例子,通常大家都是处理原始的Fortran源代码。这种做法可行吗?

1 个回答

8

我觉得你只需要用到ctypes这个库,这里有一个完整的例子,教你怎么调用一个lapack函数,你可以在这个页面找到:http://www.sagemath.org/doc/numerical_sage/ctypes.html

你可以这样获取你的函数:

import ctypes
from ctypes.util import find_library
lapack = ctypes.cdll.LoadLibrary(find_library("lapack"))
dgtsv = lapack.dgtsv_

撰写回答