ctypes: error passing a list of str to a fortran dll
luis
solisgb at gmail.com
Thu Jun 7 11:24:16 EDT 2007
On 5 jun, 06:15, Charles Sanders <C.delete_this.Sand... at BoM.GOv.AU>
wrote:
> luis wrote:
> > I'm using ctypes to call afortrandllfrom python. I have no problems
> > passing integer and double arryas, but I have an error with str arrys.
> > For example:
>
> [snip]
>
> I do not know about MicrosoftFortrancompilers (your mention
> ofdllindicates you are probably using MS), nor much about
> Python, but the C equivalent of a givenFortrancall is operating
> system and compiler dependent. You should consult theFortran
> compiler manual for the compiler used to create theDLL.
>
> Despite this, many (but not all) C toFortraninterfaces have
> the following characteristics
>
> + C name isFortranname in lower case
> +FortranREAL, DOUBLE PRECISION, INTEGER etc parameters
> are pointers to the parameter in C, ie float*, etc
> +FortranREAL etc arrays are pointers in C (same as
> C arrays decay to pointers).
> +FortranCHARACTER and CHARACTER arrays are passed as TWO
> parameters, one a pointer to the start of the variable
> or array, and the other the length as an integer, not
> a pointer. The length parameters follow all other
> parameters, in order of the character variables/arrays.
>
> Variations I have seen (all on Unix) include using upper case
> instead of lower, prepending (or postpending) an underscore (or
> other character(s)) to the subroutine or function name, and
> using special "character descriptors" (packing address and
> length into one "word") for character variables. There are
> almost certainly more variations that I have not seen.
>
> For example, given aFORTRANdeclaration
>
> SUBROUTINE X( CV, RV, CA, N )
> CHARACTER*(*) CV
> REAL RV
> CHARACTER*(*) CA(*)
> INTEGER N
>
> The C equivalent is likely to be
>
> void x( char *pcv, float *prv, char *pca, int *pn,
> int lv, int la)
>
> Where lv will hold the length of cv and la the length of
> each element of ca (required to be the same for all elements
> of the array).Fortranuses fixed length character strings,
> padded with blanks.
>
> Given the error message
>
> > ValueError: Procedure probably called with not enough
> > arguments (4 bytes missing)
>
> I suspect that yourFortrancompiler is one of the many which
> do this, and the missing 4 bytes are the integer length of
> each element of the character array.
>
> Also, I noticed you seem to be passing an array of character
> pointers rather than an array of characters. It is doubtful thatFortrancan handle this. You will probably have to pad the strings
> to a maximal length with spaces, concatanate then into one big
> string, and pass this by reference together with their padded
> length. YourFortranmay (but probably won't) have extensions
> that allow you to pass an array of character pointers.
>
> Charles
The solution proposed by Jugoslav Dujic, from comp lang fortran is
#Python script calling fortran subroutine
from ctypes import *
ap = windll.LoadLibrary(self.locationDll)
ap.TEST_02.restype=None
myCadena='D:\BBDD\PythonScripts\pru.txt'
strLen=len(myCadena)
pf_myCadena = c_char_p(myCadena)
pf_srLen = c_int(strLen)
ap.TEST_02(pf_myCadena,pf_srLen)
!fortran dll
subroutine TEST_02(s)
!DEC$ ATTRIBUTES DLLEXPORT :: TEST_02
!DEC$ATTRIBUTES REFERENCE:: s
!INTEGER(4):: n
CHARACTER(*):: s
open (unit=31,file=trim(s))
write(31,'(f0.1)') 1.0
write(31,*) trim(s)
write(31,'(i0)') len_trim(s)
close(31)
return
END subroutine
Regards
More information about the Python-list
mailing list