Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
接口Python、C和Fortran_Python_C_Fortran_Fortran Iso C Binding - Fatal编程技术网

接口Python、C和Fortran

接口Python、C和Fortran,python,c,fortran,fortran-iso-c-binding,Python,C,Fortran,Fortran Iso C Binding,我已经为python编写了一个C扩展(使用python/CAPI),它使用distutils构建,并且运行良好。现在我想在C代码中添加一些Fortran例程的包装器。我要寻找的最终结果是一个python函数,它调用一个调用Fortran函数的C函数 这可能吗?我可以从Python成功地调用C,从C成功地调用Fortran,但是我在组合这三种语言时遇到了困难。有什么想法吗?谢谢 编辑 下面是我想要的更详细的结构示例: 假设我有一个名为fortranfunc.f90的Fortran例程和一个名为c

我已经为python编写了一个C扩展(使用python/CAPI),它使用distutils构建,并且运行良好。现在我想在C代码中添加一些Fortran例程的包装器。我要寻找的最终结果是一个python函数,它调用一个调用Fortran函数的C函数

这可能吗?我可以从Python成功地调用C,从C成功地调用Fortran,但是我在组合这三种语言时遇到了困难。有什么想法吗?谢谢


编辑 下面是我想要的更详细的结构示例:

假设我有一个名为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();
}
但是我不知道如何处理对fortranfunc.f90的依赖


我希望这是平台独立的-如果这是不可能的,我会寻找另一个解决方案!感谢您迄今为止提出的所有建议。

通常,您可以在任何OBJ文件或库中调用任何导出的函数,但当涉及到不同语言的不同编译器时,问题就开始了

虽然这不是一个标准,但通常单语言编译器有自己的方便,可以装饰/损坏外部符号,以便链接器稍后使用。因此,c库中的一个函数,例如在c源代码中定义的名为“printf”的函数,将在目标文件中修饰为
“\u printf”
,然后当您尝试从另一个语言编译器调用它时,该语言编译器可能遵循不同的修饰规则。因此,当您在python源代码中以其名称
“printf”
声明它时,编译器会将其更改为类似于
\u printf\u
的其他内容

稍后,当链接器尝试解析C库和python对象文件之间的外部符号时,他会发现
“\u printf”
“\u printf”
之间不匹配,这将引发致命错误并停止构建可执行文件


< P>如果C代码的唯一目的是作为一个包装器,允许您在Python中运行FORTRAN代码,那么您可以通过直接从FORTRAN代码生成Python模块来更好地服务。

< P>我建议您考虑NUMPY对dituTIL的扩展,这将为FORTRAN提供支持。p> 值得注意的是,可以使用与
.c
源文件相同的方法包含Fortran源文件

from numpy.distutils.core import Extension, setup

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

根据。

您可以为Fortan代码使用C包装器。不确定这两种语言是否兼容ABI。我想这取决于目标平台。如果包装器只是转发所有参数1:1,这甚至可能不会生成实际代码。是的,这是可能的(我以前做过)。正确的方法取决于编译器和操作系统。编译C代码和Fortran代码时,您现在使用的编译器标志是什么?Fortran和C的互操作性甚至在标准中。看到FoTrac—ISO-C绑定…有没有一个特殊的原因来解释为什么你想要C在中间?只是一个建议。但是,如果ABI允许,它可能只需要一个C头和一个适当的Python/C-API模块。我只是不确定。当时,我有一些关于Pascal的东西,主要要求C-header中的函数反转参数列表。但那是十多年前的事了。在80年代和部分90年代,添加后缀或前缀如
\uu
很常见,但现在已经不常见了。所以你应该把你的陈述相对化。例如,gcc不再像那样修改外部符号(如果它在过去——比方说——15年中曾经这样做过的话)。然而,特别是对于Fortran,这是可能的。但问题更多的是函数参数的编组、寄存器文件布局和复合数据类型的打包。对于标量类型,大多数情况下都有简单的解决方案,因为它们大多数情况下是由硬件处理的;它不像C代码那样链接。这是关于提供一个C模块,用于在编译代码和Python程序之间进行接口。Python二进制文件确实存在,但它们是字节码(类似于Java),并在运行时加载。此外,Python代码的名称空间完全独立于编译/链接的代码。我的大部分代码都是用C编写的,因此很遗憾,我不能直接从Python调用Fortran。如果功能可以分离,您可能会创建两个模块。不幸的是,它们不是——否则我会这样做!
from numpy.distutils.core import Extension, setup

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