interfacing Python, C, and Fortran

时间:2015-05-12 22:40:30

标签: python c fortran fortran-iso-c-binding

I've written a C extension for python (using the Python/C API) that builds with distutils and works nicely. Now I want to add to that C code a wrapper for some Fortran routines. The end result I'm looking for is a python function that calls a C function that calls a Fortran function.

Is this possible? I can successfully call C from Python, and Fortran from C, but I'm having trouble combining all three. 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:

if(i >= secondDropdownNames.length)

I'm trying to build it with a setup.py file like this one:

#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();
}

But I don't know how to handle the dependency on 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.

3 个答案:

答案 0 :(得分:1)

我建议你考虑NumPy对distutils的扩展,它为Fortran http://docs.scipy.org/doc/numpy/reference/distutils.html提供了支持。

值得注意的是,您可以像对.c源文件一样包含Fortran源文件

from numpy.distutils.core import Extension, setup

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

根据Combining Python with Fortran, C and C++

答案 1 :(得分:0)

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.

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 caller.callMethod('fun', [text]); 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. 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.

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.

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

答案 2 :(得分:0)

如果C代码的唯一目的是充当包装器以允许您在Py​​thon中运行Fortran代码,那么使用f2py直接从Fortran代码生成Python模块可能会更好