简体   繁体   English

连接Python,C和Fortran

[英]interfacing Python, C, and Fortran

I've written a C extension for python (using the Python/C API) that builds with distutils and works nicely. 我已经为python编写了C扩展(使用Python / C API),该扩展使用distutils构建并且运行良好。 Now I want to add to that C code a wrapper for some Fortran routines. 现在,我想在C代码中添加一些Fortran例程的包装器。 The end result I'm looking for is a python function that calls a C function that calls a Fortran function. 我要寻找的最终结果是一个python函数,该函数调用C函数,该函数调用Fortran函数。

Is this possible? 这可能吗? I can successfully call C from Python, and Fortran from C, but I'm having trouble combining all three. 我可以从Python成功调用C,也可以从C成功调用Fortran,但是我很难将所有三个都结合在一起。 Any ideas? 有任何想法吗? Thanks! 谢谢!


EDITED Here is a more detailed example of the structure I want: 编辑这是我想要的结构的更详细的示例:

Suppose I have a Fortran routine called fortranfunc.f90, and a C code called cfunc.c which has the following form: 假设我有一个名为fortranfunc.f90的Fortran例程,以及一个名为cfunc.c的C代码,其格式如下:

#include <Python.h> 
#include<numpy/arrayobject.h> 

static PyObject *cfunc(PyObject *self, PyObject *args); 
extern double fortranfunc_(double*);  

static PyObject *cfunc(PyObject *self, PyObject *args)
{       
     /* a bunch of C code here to calculate the double x */

      y = fortranfunc_(&x);   //now call the fortran function

     /* now finish up using the value of y returned by the fortran function */
}       

static PyMethodDef cfunc_methods[] = {{"cfunc", cfunc, METH_VARARGS, NULL},{NULL}};

void initcfunc(void)
{
      Py_InitModule("cfunc", cfunc_methods);
      import_array();
}

I'm trying to build it with a setup.py file like this one: 我正在尝试使用setup.py文件来构建它,如下所示:

from distutils.core import setup, Extension
import numpy as np

module1 = Extension('cfunc', sources = ['cfunc.c'])

setup (name = 'cfunc',
        version = '1.0',
        include_dirs = [np.get_include()],
        ext_modules = [module1])

But I don't know how to handle the dependency on fortranfunc.f90. 但是我不知道如何处理对fortranfunc.f90的依赖。

I'd like this to be platform independent - if that isn't possible, I will look for another solution! 我希望它是独立于平台的-如果无法实现,我将寻找另一种解决方案! Thank you for all the suggestions so far. 谢谢您到目前为止提出的所有建议。

I would suggest you to consider the NumPy's extension to distutils, which brings support for Fortran http://docs.scipy.org/doc/numpy/reference/distutils.html . 我建议您考虑NumPy对distutils的扩展,它为Fortran提供了支持http://docs.scipy.org/doc/numpy/reference/distutils.html

Notably, you can include a Fortran source file the same way you do it for the .c source file 值得注意的是,您可以以与.c源文件相同的方式包含Fortran源文件。

from numpy.distutils.core import Extension, setup

setup(name='hw',
       ext_modules=[Extension(name='hw', sources=['../hw.f'])],
       )

according to Combining Python with Fortran, C and C++ . 根据将Python与Fortran,C和C ++结合使用

generally, you can call any exported function in any OBJ file or LIB, but when it comes to different compilers of different languages , the problems start. 通常,您可以在任何OBJ文件或LIB中调用任何导出的函数,但是当涉及到不同语言的不同编译器时,问题就开始了。

although it is not a standard ,but it's usually that the one language compilers have their convenience for decorating/mangling external symbols to be used by the linker later. 尽管这不是标准,但是通常一种语言编译器会很方便地修饰/处理稍后由链接器使用的外部符号。 so a function in the c library for example defined in the c source code by the name "printf" will be decorated in the object file to be "_printf" then when you try to call it from another language compiler, this language compiler might follow a different decoration rule. 因此,c库中的函数(例如,在c源代码中由名称"printf"定义的"printf"将在目标文件中修饰为"_printf"然后当您尝试从另一种语言编译器进行调用时,该语言编译器可能会跟随不同的装饰规则。 so when you declare it in your python source code with it's name "printf" , the compiler will mangled it to be something else like _printf_ for instance. 因此,当您在python源代码中将其声明为"printf" ,编译器会将其_printf__printf_类的东西。

later when the linker tries to resolve external symbols between the C library and your python object file he will find mismatch between "_printf" and "_printf_" , which will raise a fatal error and stop building the executable. 当连接器尝试解析C库和你的Python对象文件,他会发现之间的不匹配之间的外部符号后"_printf""_printf_" ,这将提高一个致命的错误,并停止生成可执行。

http://en.wikipedia.org/wiki/Name_mangling http://en.wikipedia.org/wiki/Name_mangling

如果C代码的唯一目的是充当包装程序以允许您在Py​​thon中运行Fortran代码,则可以最好使用f2py从Fortran代码直接生成Python模块, 从而为您提供更好的服务。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM