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

Cannot pass variable by Value from Fortran to C

Michel_L_
Beginner
848 Views

I have a problem to pass a integer value from Fortran to C.

I use Visual Studio 2013 with Visual Fortran 14 and even using the declaration INTEGER(C_INT), VALUE :: myValue,

the receiving C function get the address of myValue instead of the value.

Is there any explanation.

Regards

0 Kudos
6 Replies
IanH
Honored Contributor III
848 Views

I only have VS2010, but it works for me.

/* 2014-05-19 interop-c.c */
#include <stdio.h>

void c_function(int a)
{
   printf("The dummy argument has value %d and address %p", a, &a);
}
PROGRAM Interop
  USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_INT, C_LOC, C_INTPTR_T
  IMPLICIT NONE
  INTERFACE
    SUBROUTINE c_function(a) BIND(C, NAME='c_function')
      USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_INT
      IMPLICIT NONE
      INTEGER(C_INT), VALUE :: a
    END SUBROUTINE c_function
  END INTERFACE
  INTEGER(C_INT) :: arg
  CHARACTER(*), PARAMETER :: fmt_ptr = 'Z16.16'   ! 64 bit
!  CHARACTER(*), PARAMETER :: fmt_ptr = 'Z8.8'    ! 32 bit
  arg = 6
  PRINT "('The actual argument has value ',I0,' and address '" // fmt_ptr // ")",  &
      arg, TRANSFER(C_LOC(arg), 1_C_INTPTR_T)
  CALL c_function(arg)
END PROGRAM Interop
>cl /c "2014-06-19 interop-c.c"
Microsoft (R) C/C++ Optimizing Compiler Version 16.00.40219.01 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

2014-06-19 interop-c.c

>ifort "2014-06-19 interop-fort.f90" "2014-06-19 interop-c.obj"
Intel(R) Visual Fortran Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 14.0.3.202 Build 201404
22
Copyright (C) 1985-2014 Intel Corporation.  All rights reserved.

Microsoft (R) Incremental Linker Version 10.00.40219.01
Copyright (C) Microsoft Corporation.  All rights reserved.

"-out:2014-06-19 interop-fort.exe"
-subsystem:console
"2014-06-19 interop-fort.obj"
"2014-06-19 interop-c.obj"

>"2014-06-19 interop-fort.exe"
The actual argument has value 6 and address 000000013F7BF058
The dummy argument has value 6 and address 000000000031F950

 

0 Kudos
Michel_L_
Beginner
848 Views

Thank for the comment.

I use the same kind of declaration and it does  not work for me.

What is strange is when i use the Fortran-Calls-C sample of the mixed language Intel sample, it works but when using my project (converted from F77) it does not work.

Here are my compilation command line for Fortran LIB.

/nologo /debug:full /Od /warn:interfaces /integer_size:16 /Qzero /module:"Debug\\" /object:"Debug\\" /Fd"Debug\vc120.pdb" /traceback /check:bounds /check:stack /libs:dll /threads /dbglibs /c

Here are my compilation command line for my Windows MFC App that call FORTRAN LIB and that FORTRAN LIB call back some function in C in my MFC App that cannot receive value parametes from FORTRAN.

/Yu"stdafx.h" /GS /analyze- /W3 /Zc:wchar_t  /ZI /Gm- /Od /sdl /Fd"Debug\vc120.pdb" /fp:precise /Zp2 /D "WIN32" /D "_WINDOWS" /D "_DEBUG" /D "_USING_V110_SDK71_" /D "_UNICODE" /D "UNICODE" /D "_AFXDLL" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /Oy- /MDd /Fa"Debug\" /EHsc /nologo /Fo"Debug\" /Fp"Debug\WireStudio.pch"

I use the integer_size:16 because the Fortran Lib come's form an old solution running in 16bits.

Any new advice will be great.

Best regards

0 Kudos
IanH
Honored Contributor III
848 Views

Show the relevant bits of your code - declarations (C++ and Fortran) and the call on the Fortran side.

0 Kudos
TimP
Honored Contributor III
848 Views

Do you mean you expect integer_size:16 to change C_INT to C_INT16_T ?   I don't expect that to happen, as specified KINDs don't change under integer_size options.  A simple example of what you mean would go a long way.

0 Kudos
Lorri_M_Intel
Employee
848 Views

In the absence of BIND (C), the VALUE attribute does not pass-by-value; it generates a temp and passes the address of that temp.

If you declare the external routine as having BIND(C) attributes, then the VALUE attributes does pass the argument by-value.

We did have a bug where we were not honoring that; I'm not sure which release we fixed it, so you might try adding /assume:std_value to your command line.   If you already have the fixed version, it will have no effect.

            --Lorri

0 Kudos
Steven_L_Intel1
Employee
848 Views

The bug Lorri refers to doesn't affect the case Michel describes - it was only for small structures and was fixed in 14.0.1.

Michel, please show us your actual Fortran code. In particular, does the Fortran interface specify BIND(C) or not? If it doesn't, and Fortran 2003 semantics are being followed, then specifying VALUE would NOT pass by value, it would pass the address of a copy of the argument. This isn't the default currently (it will be in 15.0) - you get it if you say /standard-semantics or /assume:std_value.

It's difficult to know exactly what the problem is without seeing your actual code. Descriptions and saying your interface is "like" an example are not useful.

0 Kudos
Reply