Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28456 Discussions

Interoperability: Fortran Calling C and passing and integer

gandresr
Beginner
869 Views

Hello,

 

I am trying to run a C function from a Linux shared library (.so) from Fortran. The function in C receives an integer number from the Fortran program. I am not getting the right result in C. There seems to be a type error that I can't identify. I am creating an abstract interface following the syntax for interoperability established here 

 

Function in C:

int print_number(int n)
{
    printf("Hello world! %d\n", n);
    return 0;
}​

Function in Fortran

! Interface with shared library
abstract interface
    !% -------------------------------------------------------------------------------
    !% Simulation
    !% -------------------------------------------------------------------------------
    integer function print_number(number)
        use, intrinsic :: iso_c_binding
        implicit none
        integer(c_int), value :: number
    end function print_number
end interface

 

The output when calling print_number(2):

Hello world! 734920112

  

I am attaching the files to reproduce the error. First, execute `./compile.sh`, then `./run_test

I would appreciate it a lot if someone could point out what I am doing wrong.

 

Thanks!

0 Kudos
1 Solution
Khalik_K_Intel
Moderator
825 Views

Hello,


Thank you for contacting Intel Support.

As specified earlier by Arjen_Markus, you are not using "bind(C)" attribute for the abstract interface.

This is why you are getting wrong results in you application.


BIND is the language-binding-spec attribute which in this case should be used to specify the interface of an external interoperable procedure.

For more info please see: https://www.intel.com/content/www/us/en/develop/documentation/fortran-compiler-oneapi-dev-guide-and-reference/top/compiler-reference/mixed-language-programming/standard-tools-for-interoperability/bind.html


So, the only thing you need to change is to modify the following line in "interface.f90":

From: integer function print_number(number)

To:     integer function print_number(number) BIND(C)


I check the result on my end and it is as expected:

$ . compile.sh

$ ./run_test

Hello world! 2

$ ./run_test

Hello world! 2

$ ./run_test

Hello world! 2


Hope that this helps.


Regards,

Khalik.



View solution in original post

0 Kudos
5 Replies
Arjen_Markus
Honored Contributor I
846 Views

Your code is loading the library and then retrieving a pointer to the function. So it is a bit more complicated than what you sketched. I do not see anything obviously wrong, but you do not use the "bind(C)" attribute for the abstract interface. I am sure this is not really the problem, but it might be cleaner. Another thing: you pass in the literal number 2 (default integer), but the function expects an integer of type c_int. You should try with 2_c_int or something similar.

0 Kudos
Khalik_K_Intel
Moderator
826 Views

Hello,


Thank you for contacting Intel Support.

As specified earlier by Arjen_Markus, you are not using "bind(C)" attribute for the abstract interface.

This is why you are getting wrong results in you application.


BIND is the language-binding-spec attribute which in this case should be used to specify the interface of an external interoperable procedure.

For more info please see: https://www.intel.com/content/www/us/en/develop/documentation/fortran-compiler-oneapi-dev-guide-and-reference/top/compiler-reference/mixed-language-programming/standard-tools-for-interoperability/bind.html


So, the only thing you need to change is to modify the following line in "interface.f90":

From: integer function print_number(number)

To:     integer function print_number(number) BIND(C)


I check the result on my end and it is as expected:

$ . compile.sh

$ ./run_test

Hello world! 2

$ ./run_test

Hello world! 2

$ ./run_test

Hello world! 2


Hope that this helps.


Regards,

Khalik.



0 Kudos
andrew_4619
Honored Contributor II
782 Views
! Interface with shared library
abstract interface
    function print_number(number) bind(C)
        use, intrinsic :: iso_c_binding
        implicit none
        integer(c_int) :: print_number ! note function type also
        integer(c_int), value :: number
    end function print_number
end interface
0 Kudos
Khalik_K_Intel
Moderator
742 Views

Hello,


Has your issue been solved or do you have any questions on this?


Regards,

Khalik.


0 Kudos
Khalik_K_Intel
Moderator
698 Views

This issue has been resolved and we will no longer respond to this thread. If you require additional assistance from Intel, please start a new thread.

Any further interaction in this thread will be considered community only.


0 Kudos
Reply