这是我的第一个问题,所以对我好一点。
我用的是1.6.1版本的f2py。我有一个fortran模块,其中包含几个编译(和工作)非常好的子程序。但是,其中一个使用erf(x)函数,它是GNU扩展。对于我的目的来说,它不够精确,所以我尝试使用外部erf实现。
我正在尝试使用fortran 77中的数字配方中的一个——在这里,我将所有相关函数复制到一个名为“erf.f”的文件中,该文件与我的模块位于同一文件夹中。我在模块文件的顶部使用include 'erf.f'。我将erf函数的实际名称更改为“derf”,因此它不会与gfortran erf扩展冲突。
但是,当我试图通过f2py编译时,“erf.f”中的每个函数foo都给出了错误
错误:“foo”的重新定义
错误:“foo”的先前定义在此处
当我看到c文件时,它被提到包含了重新定义和先前的定义,这个函数看起来确实存在两次。我只是不知道为什么?
有人知道怎么解决这个问题吗?干杯。
编辑:我没有提到(因为我认为这是不必要的额外信息)f2py被numpy distutils用来创建扩展。我现在提到它的原因是,我发现可以用f2py -c my_module.f90 -m mod创建扩展fine,但是当运行python setup.py install时,我得到了上面详细描述的错误。那么f2py在运行distutils时有什么不同之处呢?
编辑2:如果我把外部erf函数文件的所有内容放在与模块相同的文件中,那么一切都会正常工作。我真的不想这样做,因为展望未来,我会有一个庞大的文件,但它会工作到现在,直到我得到了这个问题的答案。

最佳答案

一种解决方案是创建一个模块erf.f90,并使用use erf(或其名称)将其导入主代码中。
我在f2py导入扩展名为.f的模块时遇到了一些奇怪的问题,您只需将erf.f重命名为erf.f90并在使用-ffixed-form编译时指定gfortran即可使其正常工作。
编辑:
如果使用use导入模块,则无需同时使用includeinclude基本上是在主代码的源代码中包含erf.f的实际代码(尽管正如您所注意到的,它的行为与直接在主文件中键入erf.f并不完全相同),而use告诉编译器寻找预编译的模块。
我发现use在使用模块和f2py时对我很有效。(我的代码基本上是固定格式的Fortran 90)。假设主文件main.f和模块subs.f90(确保module...end module中存在subs.f90,我将使用以下顺序进行编译:

gfortran -ffixed-form -c subs.f90
f2py.py -c -m main -I/path/to/subs /path/to/subs/subs.f90 main.f

请注意,根据您的系统,您可能需要指定其他选项来f2py。对我来说,在Windows上使用MinGW,我需要--compiler=mingw32,因为f2py似乎无法找到C编译器。

10-05 22:16