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

Passing data from Fortran to C

DJ64
Beginner
1,028 Views

Hi

I have a program running perfectly in 32bit, with intel Fortran in VS15.  Changing to 64 bit disrupted everything. 

the data is transfered between the Fortran and C functions by a common block. Before calling the C function from the Fortran, an interface is declared:

INTERFACE
SUBROUTINE c_void_name() BIND(C, NAME="c_void_name")
END SUBROUTINE c_void_name

END INTERFACE

and in the common block the declaretion is 

!DEC$ ATTRIBUTES ALIAS:'_c_data_input_structure_name' :: fortran_common_name

the passes the compilation perfectly, but the variables are all zero, and the address in the C void is not the same as the address seen in the by the Fortran program.

As I wrote before, in 32 bit it worked fine.

I'll be thankfull for your help

DJ64

Labels (1)
0 Kudos
5 Replies
andrew_4619
Honored Contributor III
1,008 Views

From the fragments shown I think we can only make wild guesses. It would be better to post two short bits of code for Fortran and C that demonstrate the issue. That can be examined an built by others. The answer will I think then be evident.

andrew_4619
Honored Contributor III
1,002 Views
0 Kudos
DJ64
Beginner
949 Views

Sorted It out. The attribute should be

 !DEC$ ATTRIBUTES ALIAS:'c_data_input_structure_name' :: fortran_common_name

and not

!DEC$ ATTRIBUTES ALIAS:'_c_data_input_structure_name' :: fortran_common_name

i.e. the ALIAS name in 64bit should be without an underscore in the name.

Thanks

0 Kudos
FortranFan
Honored Contributor III
920 Views

@DJ64 wrote:

Sorted It out. The attribute should be

 !DEC$ ATTRIBUTES ALIAS:'c_data_input_structure_name' :: fortran_common_name

and not

!DEC$ ATTRIBUTES ALIAS:'_c_data_input_structure_name' :: fortran_common_name

i.e. the ALIAS name in 64bit should be without an underscore in the name.

Thanks


Given your original post with an INTERFACE using C interoperability facilities, you may want to consider the same for COMMON blocks as well and get a standard approach with portability across platforms and compilers.

bind(C, name="c_struct_name") / common_name /

A fully worked out example:

module m
   use, intrinsic :: iso_c_binding, only : c_int, c_float
   ! Global variables
   integer(c_int) :: n
   real(c_float) :: r
   common / foodata / n, r
   bind(C, name="foo") / foodata /
contains
   subroutine Fsub() bind(C, name="Fsub")
      n = 42
      r = 99.0
   end subroutine 
end module 
#include <stdio.h>

typedef struct {
   int n;
   float r;
} foo_c;
extern foo_c foo;

// Fortran function
void Fsub();

int main()
{
   Fsub();
   printf("In C main: foo.n = %d, foo.r = %f\n", foo.n, foo.r);
   return 0;
}
C:\temp>ifort /c /standard-semantics /free m.f
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.10.0 Build 20230609_000000
Copyright (C) 1985-2023 Intel Corporation.  All rights reserved.


C:\temp>cl /c /W3 /EHsc c.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.36.32537 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

c.c

C:\temp>link c.obj m.obj /subsystem:console /out:c.exe
Microsoft (R) Incremental Linker Version 14.36.32537.0
Copyright (C) Microsoft Corporation.  All rights reserved.


C:\temp>c.exe
In C main: foo.n = 42, foo.r = 99.000000

 

0 Kudos
Steve_Lionel
Honored Contributor III
926 Views

This is perhaps why you should use BIND(C,NAME=) if you can - it automatically deals with name decoration.

0 Kudos
Reply