簡體   English   中英

使用ctypes調用FORTRAN DLL

[英]Calling a FORTRAN DLL using ctypes

我正在嘗試學習如何將FORTRAN代碼整合到DLL中,可以使用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) 

誰能提供解決方案?

謝謝

Fortran通常是按引用傳遞的。 從其他語言(如C)進行調用時,這意味着將內存地址傳遞到Fortran子例程中。 顯然,Python實現是相似的。 在您進行編輯之前,您遇到一個錯誤,提示“類似在0x000003處的非法訪問”之類的內容,該值與您試圖作為該值傳遞的值“ 3”相同。 您剛剛輸入了Fortran子例程,但是當它嘗試進行添加時,它將在內存位置3處查找整數,而不是在加法本身中使用值3。

編輯后,您將傳遞一個指針(我認為基於我的評論)。 那給出了一個不同的錯誤。 這表明您傳遞了一個額外的參數,因為它比預期多了4個字節的數據。 我認為這可能是某些32位庫和某些64位庫之間的不兼容,其中4個字節在兩種體系結構的指針之間可能存在長度差異。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM