Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
Welcome to the Intel Community. If you get an answer you like, please mark it as an Accepted Solution to help others. Thank you!
26758 Discussions

Fortran 11 and probable 2003 compatibility issue

laurent_l_
Beginner
125 Views

Hi

I'm using Intel Fortran 11 to create a Fortran-Call-C piece of code

I have problem when passing arguments by value from Fortran to C, and I was wondering if this may come from 2003 support issues in ifort 11

The fortran sends a single argument by value

ival=1 in CALL  p_f_i_AMETest(ival)  

but the C function get the adress instead of the value, and print

ival =1703488 in void AMETest(int ival) 

 

many thanks for any tips !!

Laurent

 

 

This is my code

TestDLL.cpp

extern "C" TESTDLL_API void AMETest(int ival) {

    printf("ival =%d\n",ival);

};

 

Main.f90

PROGRAM main
        !DEC$ REAL:8
        USE DLLinterface

        CHARACTER*200:: dllname = 'TestDLL.dll'

        Call Test(dllname)
   
END PROGRAM

 

DLLinterface.f90

MODULE DLLinterface
      
      USE kernel32

      USE, INTRINSIC:: iso_c_binding


      ABSTRACT INTERFACE
        SUBROUTINE f_i_AMETest(ival) BIND(C,name='AMETest')
            use iso_c_binding, only: c_int
            integer(c_int), VALUE :: ival     
        END SUBROUTINE f_i_AMETest
      END INTERFACE
      

      INTEGER(HANDLE):: handleDLL
      PROCEDURE(f_i_AMETest), POINTER:: p_f_i_AMETest     
      TYPE(C_FUNPTR):: p_c_function
      INTEGER(C_INTPTR_T):: addressCpointer
      INTEGER(C_INT):: returnedValue
    
      CONTAINS
        SUBROUTINE Test(DLLname)

            CHARACTER*200, INTENT(IN):: DLLname
            TYPE(C_FUNPTR):: p_c_function
            INTEGER(C_INTPTR_T):: addressCpointer
            INTEGER(C_INT):: returnedValue
            INTEGER(C_INT):: ival
            
            ival=1 
      
            
            handleDLL = LoadLibrary(DLLname)
            
            IF (handleDLL == NULL) THEN
                WRITE(*,*) 'DLLinterface: could not import the DLL'
            ELSE
                WRITE(*,*) 'DLLinterface: DLL imported'
            END IF
            addressCpointer = GetProcAddress(handleDLL, &
                                            'AMETest')
            
            !cast address to a c fonction pointer, then fortran
            CALL C_F_PROCPOINTER( &
                           TRANSFER(addressCpointer,p_c_function), &
                           p_f_i_AMETest)
  
            CALL  p_f_i_AMETest(ival)  

     
       END SUBROUTINE Test
END MODULE DLLinterface

 

 

0 Kudos
1 Solution
Lorri_M_Intel
Employee
125 Views

I don't have an 11.x compiler available to try this myself, but let me suggest this:

Try adding an explicit %VAL() in your call, as:   CALL  p_f_i_AMETest(%val(ival))

if that gives a compile-time error, let's try using the non-standard directive in the abstract routine declaration:

!DEC$ ATTRIBUTES VALUE :: ival

                  --Lorri

 

View solution in original post

4 Replies
Steve_Lionel
Black Belt Retired Employee
125 Views

You are using a compiler that is some seven (or more!) years old. I have a vague recollection of an old issue with VALUE not being recognized from an ABSTRACT INTERFACE. Please try it with a current compiler (version 17 is current.)

laurent_l_
Beginner
125 Views

Thanks Doctor Fortran !

Yes I know that my version is old, but I have no other release available right now (and not sure we will buy a new one or update just for the topic I am currently working for)

Any workaround possible in this case ? I really need to load a DLL because this piece of code have to be integrated in an another process.

Thanks

 

Lorri_M_Intel
Employee
126 Views

I don't have an 11.x compiler available to try this myself, but let me suggest this:

Try adding an explicit %VAL() in your call, as:   CALL  p_f_i_AMETest(%val(ival))

if that gives a compile-time error, let's try using the non-standard directive in the abstract routine declaration:

!DEC$ ATTRIBUTES VALUE :: ival

                  --Lorri

 

View solution in original post

laurent_l_
Beginner
125 Views

Great ! it has worked !

I need to run more tests with other functions and more arguments, but I'm on the good way now :)

Many thanks Lorri :)

 

Reply