我正在尝试学习如何将FORTRAN代码编译成我可以使用ctypes从Python调用的DLL。即使是一个简单的例子也不起作用,任何人都可以帮忙吗?
我在FORTRAN中有一个程序:
subroutine ex(i)
integer i
i=i+1
return
end
然后我尝试从Python
运行它我用MinGW编译器编译它如下
gfortran -c test.f
gfortran -shared -mrtd -o test.dll test.o
查看创建的DLL,我看到了
Microsoft (R) COFF/PE Dumper Version 12.00.30723.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file test.dll
File Type: DLL
Section contains the following exports for test.dll
00000000 characteristics
0 time date stamp Thu Jan 01 13:00:00 1970
0.00 version
1 ordinal base
1 number of functions
1 number of names
ordinal hint RVA name
1 0 00001280 ex_
Summary
1000 .CRT
1000 .bss
1000 .data
1000 .edata
1000 .eh_fram
1000 .idata
1000 .rdata
1000 .reloc
1000 .text
1000 .tls
然后我尝试从Python
访问它from ctypes import *
DLL = windll.test
print DLL
print getattr(DLL,'ex_')
print DLL[1]
print DLL.ex_
x = pointer( c_int(3) )
DLL.ex_( x )
输出
<WinDLL 'test', handle 6bec0000 at 2143850>
<_FuncPtr object at 0x020E88A0>
<_FuncPtr object at 0x020E8918>
<_FuncPtr object at 0x020E88A0>
Traceback (most recent call last):
File "C:\proj_py\test.py", line 20, in <module>
DLL.ex_( x )
ValueError: Procedure probably called with too many arguments (4 bytes in excess)
所以虽然函数在那里,但我没有正确地调用它。我很难过。
我在64位Windows-7机器上使用python 2.7.10(32位),我有一个最新版本的MinGW编译器:
$ gfortran -v
Using built-in specs.
COLLECT_GCC=c:\mingw\bin\gfortran.exe
COLLECT_LTO_WRAPPER=c:/mingw/bin/../libexec/gcc/mingw32/4.8.1/lto-wrapper.exe
Target: mingw32
Configured with: ../gcc-4.8.1/configure --prefix=/mingw --host=mingw32 --build=mingw32 --without-pic --enable-shared --e
nable-static --with-gnu-ld --enable-lto --enable-libssp --disable-multilib --enable-languages=c,c++,fortran,objc,obj-c++
,ada --disable-sjlj-exceptions --with-dwarf2 --disable-win32-registry --enable-libstdcxx-debug --enable-version-specific
-runtime-libs --with-gmp=/usr/src/pkg/gmp-5.1.2-1-mingw32-src/bld --with-mpc=/usr/src/pkg/mpc-1.0.1-1-mingw32-src/bld --
with-mpfr= --with-system-zlib --with-gnu-as --enable-decimal-float=yes --enable-libgomp --enable-threads --with-libiconv
-prefix=/mingw32 --with-libintl-prefix=/mingw --disable-bootstrap LDFLAGS=-s CFLAGS=-D_USE_32BIT_TIME_T
Thread model: win32
gcc version 4.8.1 (GCC)
有人能提供解决方案吗?
由于
答案 0 :(得分:2)
Fortran通常是通过引用传递的。从C等其他语言调用时,这意味着将内存地址传递给Fortran子例程。显然Python的实现是类似的。在您编辑之前,您遇到的错误表示类似于&#34;非法访问0x000003&#34;这是可疑的相同价值&#34; 3&#34;正如你试图传递的那样。你很好地进入了Fortran子程序,但是当它尝试进行添加时,它在内存位置3中查找整数,而不是在加法本身中使用值3。
编辑后,你传递一个指针(根据我的评论,我认为)。这给出了不同的错误。它建议您传递一个额外的参数,因为它比预期的数据多4个字节。我认为这可能是某些32位库和一些64位库之间的不兼容,4个字节可能是两个架构中指针之间长度的差异。