[Numpy-discussion] Calling routines from a Fortran library using python

Nils Wagner nwagner@iam.uni-stuttgart...
Thu Mar 11 07:06:19 CST 2010


On Thu, 11 Mar 2010 13:42:43 +0100
  Dag Sverre Seljebotn <dagss@student.matnat.uio.no> 
wrote:
> Nils Wagner wrote:
>> On Thu, 11 Mar 2010 13:01:33 +0100
>>   Dag Sverre Seljebotn <dagss@student.matnat.uio.no> 
>> wrote:
>>   
>>> Nils Wagner wrote:
>>>     
>>>> On Mon, 22 Feb 2010 22:18:23 +0900
>>>>   David Cournapeau <cournape@gmail.com> wrote:
>>>>   
>>>>       
>>>>> On Mon, Feb 22, 2010 at 10:01 PM, Nils Wagner
>>>>> <nwagner@iam.uni-stuttgart.de> wrote:
>>>>>
>>>>>     
>>>>>         
>>>>>> ar x test.a
>>>>>> gfortran -shared *.o -o libtest.so -lg2c
>>>>>>
>>>>>> to build a shared library. The additional option -lg2c 
>>>>>> was
>>>>>> necessary due to an undefined symbol: s_cmp
>>>>>>       
>>>>>>           
>>>>> You should avoid the -lg2c option at any cost if 
>>>>> compiling with
>>>>> gfortran. I am afraid that you got a library compiled 
>>>>> with g77. If
>>>>> that's the case, you should use g77 and not gfortran. 
>>>>> You cannot mix
>>>>> libraries built with one with libraries with another.
>>>>>
>>>>>     
>>>>>         
>>>>>> Now I am able to load the shared library
>>>>>>
>>>>>> from ctypes import *
>>>>>> my_lib = CDLL('test.so')
>>>>>>
>>>>>> What are the next steps to use the library functions
>>>>>> within python ?
>>>>>>       
>>>>>>           
>>>>> You use it as you would use a C library:
>>>>>
>>>>> http://python.net/crew/theller/ctypes/tutorial.html
>>>>>
>>>>> But the fortran ABI, at least for code built with g77 
>>>>> and gfortran,
>>>>> pass everything by reference. To make sure to pass the 
>>>>> right
>>>>> arguments, I strongly suggest to double check with the 
>>>>> .h you
>>>>> received.
>>>>>
>>>>> cheers,
>>>>>
>>>>> David
>>>>> _______________________________________________
>>>>> NumPy-Discussion mailing list
>>>>> NumPy-Discussion@scipy.org
>>>>> http://mail.scipy.org/mailman/listinfo/numpy-discussion
>>>>>     
>>>>>         
>>>> Hi all,
>>>>
>>>> I tried to run the following script.
>>>> The result is a segmentation fault.
>>>> Did I use byref correctly ?
>>>>
>>>> from ctypes import *
>>>> my_dsio = CDLL('libdsio20_gnu4.so')      # loading 
>>>> dynamic 
>>>> link libraries
>>>> #
>>>> # FORTRAN : CALL DSIO(JUNCAT,FDSCAT,IERR)
>>>> # 
>>>> #     int 
>>>>         I,J,K,N,IDE,IA,IE,IERR,JUNIT,JUNCAT,NDATA,NREC,LREADY,ONE=1;
>>>> #     Word        BUF[100],HEAD[30];
>>>> #     char        *PATH,*STRING;
>>>> #     char        *PGNAME,*DATE,*TIME,*TEXT;
>>>> #     int         LHEAD=30;
>>>> #
>>>> # C       : DSIO(&JUNCAT,FDSCAT,&IERR,strlen(FDSCAT));
>>>> #
>>>>
>>>>
>>>> IERR    = c_int()
>>>> FDSCAT  = c_char_p('dscat.ds')
>>>> JUNCAT  = c_int()
>>>> LDSNCAT = c_int(len(FDSCAT.value))
>>>> print
>>>> print 'LDSNCAT', LDSNCAT.value
>>>> print 'FDSCAT' , FDSCAT.value  , len(FDSCAT.value)
>>>>
>>>> my_dsio.dsio(byref(JUNCAT),byref(FDSCAT),byref(IERR),byref(LDSNCAT)) 
>>>> # segmentation fault
>>>> print IERR.value
>>>>
>>>>
>>>> Any idea ?
>>>>   
>>>>       
>>> You shouldn't have byref on FDSCAT nor LDSNCAT, as 
>>> explained by this line:
>>>
>>> # C       : DSIO(&JUNCAT,FDSCAT,&IERR,strlen(FDSCAT));
>>>
>>> Dag Sverre
>>>     
>>   
>>
>> Sorry, I am newbie to C. What is the correct way ?
>>
>>   
> 
> my_dsio.dsio(byref(JUNCAT),FDSCAT,byref(IERR),LDSNCAT) 
> 
> Dag


Great. It works like a charme.
How can I "translate" the following C-code into Python ?
I don't know how to handle HEAD and memcpy ?
Any pointer would be appreciated.

Thanks in advance.


       typedef union {
	int	i;
	float	f;
	char	c[4];
	} Word;

       int	 
 I,J,K,N,IDE,IA,IE,IERR,JUNIT,JUNCAT,NDATA,NREC,LREADY,ONE=1;
       Word	  BUF[100],HEAD[30];

       for (I=5;I<LHEAD;I++)
	HEAD[I].i = 0;
       HEAD[ 0].i =   1;
       HEAD[ 1].i =  LHEAD + NDATA*7;
       HEAD[ 2].i =  LHEAD;
       HEAD[ 3].i =  NDATA;
       HEAD[ 4].i =   7;
       memcpy (HEAD[ 7].c,"DSIO",4);
       memcpy (HEAD[ 8].c,"TEST",4);
       memcpy (HEAD[ 9].c,"NPCO",4);
       memcpy (HEAD[10].c,"    ",4);
       memcpy (HEAD[11].c,"DSIO",4);
       HEAD[20].i =   1;
       HEAD[21].i =  NDATA;
       STRING = "MM      RAD";
       DSEINH(STRING,&HEAD[24].i,&ONE,
	     strlen(STRING));


More information about the NumPy-Discussion mailing list