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

How to pass data/pointer between C/C++ and Fortran code?

Zhanghong_T_
Novice
3,402 Views

Dear all,

I am trying to compile some code that can work on Linux system to Windows 7 64bit + VS2013 + Intel Fortran. I have successfully compiled the code but the data are not passed correctly. For example, the following are Fortran code and C code:

Fortran:

      pointer (pptr,prolog), (eptr,epilog)
      integer prolog(*), epilog(*)
 
      include 'mm2000.h'
 
      integer array_bytes, block_bytes
      integer index, j, iptrsize
...
      pptr = util_malloc(block_bytes)

C:

void* UTIL_MALLOC(long long nbytes)
{ /* util_malloc  */
	void* iptout = NULL;

  if(!(iptout= malloc(nbytes))) {
    printf("UTIL_MALLOC: Out of memory, malloc return: %p \n",iptout);
    printf("   Requested value: %f = %4d bit unsigned int \n",(float)nbytes,sizeof(nbytes));
    return NULL;

  } /* if */

  return iptout;
} /* util_malloc */

 

Now the data are pass from Fortran to C, In Fortran side block_bytes=416, but in C the nbytes=1625144.

Another C example:

int_ptrsize UTIL_SUM_ADDR(long long* a, long long* b)
{ /* util_sum_addr */
  return *a + *b;
} /* util_sum_addr */

void* UTIL_REALLOC(void** iptr, long long* nwords)
{ /* util_realloc */
  void* iptout = NULL;
  long long nbytes = 0;

  nbytes = (*nwords);

  if (!(iptout= realloc(*iptr,nbytes))) {
    printf("UTIL_REALLOC: Reallocation error - aborting\n");
    printf("   Requested value: %f = %4d bit unsigned int \n",(float)nbytes,sizeof(nbytes));

    /*  exit(1); */
    return NULL;

  } /* if */

  return iptout;
} /* util_realloc */

 

In Fortran code, the function is as follows:

      pointer (pptr,prolog), (eptr,epilog)
      integer prolog(*), epilog(*)
       integer array_bytes, block_bytes, iptrsize
...
      pptr = util_realloc(pptr, block_bytes)
      eptr = util_sum_addr(aptr, array_bytes)

 

 

How to modify C/Fortran code to let the function be executed correctly?

Thanks,

Tang Laoya

0 Kudos
29 Replies
Zhanghong_T_
Novice
594 Views

Dear Steve,

Thank you very much for your kindly reply. I am sorry I don't have change to check this post until today. I tried to modify 'C_PTR' to 'C_INTPTR_T' as you said, but the following error displayed:

Error    1     error #6463: This is not a derived type name.   [C_INTPTR_T]  

What could lead to this error message?

Thanks,

Tang Laoya

0 Kudos
Zhanghong_T_
Novice
594 Views

Dear FortranFan,

Thank you very much for your kindly reply. In a word, what I need is just like what the Fortran code can do in the original code built by gfortran compiler in Linux: the parameters passed to function 'util_realloc' could be 'any kind', for example, integer*4, integer*8 (or integer(C_LONG_LONG)), or character. I don't know how to add an interface to meet this requirement (it seems that in gfortran compiler this interface is not needed).

In your example, the C code is replaced by 'Cout', but I wish the C code be unchanged and I will try to add some interface to let it work.

Thanks,

Tang Laoya

0 Kudos
Zhanghong_T_
Novice
594 Views

Oh I see, I should modify 'type(C_PTR)' to ''integer(C_LONG_LONG), before this I modified to 'type(C_LONG_LONG)'.

Thanks,

Tang Laoya

0 Kudos
Steve_Lionel
Honored Contributor III
594 Views

I had said "integer(C_INTPTR_T)"

0 Kudos
FortranFan
Honored Contributor II
594 Views

Zhanghong T. wrote:

..I wish the C code be unchanged ..

@Tang Laoya,

Why?  Meaning why do you wish the C code be unchanged?

The code you have shown thus far in C only appear to have functions such as UTIL_REALLOC that are questionable in their intent and they may have other use cases than what you have in mind.  Note all they seem to do is to be WRAPPERs to C standard library functions that can be invoked directly from Fortran if needed, but even that seems UNNECESSARY given the dynamic allocation facilities in Fortran.

Also, you mention gfortran: why don't you show a complete working C library and a Fortran program example with gfortran?  If you are using standard Fortran facilities with such an example, it will work with Intel Fortran compiler as well.  By the way, note integer*4 and integer*8 are non-standard extensions.

0 Kudos
FortranFan
Honored Contributor II
594 Views

Zhanghong T. wrote:

Dear FortranFan,

..what I need is just like what the Fortran code can do in the original code built by gfortran compiler in Linux: the parameters passed to function 'util_realloc' could be 'any kind', for example, integer*4, integer*8 (or integer(C_LONG_LONG)), or character. I don't know how to add an interface to meet this requirement (it seems that in gfortran compiler this interface is not needed). .

@Tang Laoya,

By the way, the C function you show for UTIL_REALLOC has some superfluous aspects with the use of ** referencing (pointer to pointer) and potentially non-portable aspects with C long long datatype that is confusing you with all the questions you are asking of Steve Lionel.  Look into size_t data type in C for the second parameter that appears intended to pass the number of bytes and you can do it by value also; this can be a portable option you can consider that will work with 32-bit and 64-bit target platforms as well as different compilers:

#include <stdlib.h>
#include <stdio.h>

void* UTIL_REALLOC(void* iptr, size_t nbytes)
{ /* util_realloc */
	void* iptout = NULL;

	if (!(iptout = realloc(iptr, nbytes))) {

		printf("UTIL_REALLOC: Reallocation error - aborting\n");
		printf("   Requested value: %zd = %zd bit unsigned int \n", nbytes, sizeof(nbytes));

		/*  exit(1); */
		return NULL;

	} /* if */

	return iptout;
} /* util_realloc */

Note the interface to above in Fortran is simply:

      function UTIL_REALLOC( ptr, nbytes ) result(ret) bind(C,name='UTIL_REALLOC')
         use, intrinsic :: iso_c_binding, only : c_ptr, c_size_t
         implicit none
         ! Argument list
         type(c_ptr), intent(in), value       :: ptr
         integer(c_size_t), intent(in), value :: nbytes
         ! Function result
         type(c_ptr) :: ret
      end function UTIL_REALLOC

Note the above can be used to realloc different types of data such as integer, floating-point, char/string, or any other since the first parameter and the function result are void *.

That is, you don't really show why you need to do the following:

useless.png

But again, you don't really need to use such utility functions in Fortran, especially if you want to have portable code that works with one compiler on one OS and another compiler on another OS.

 

0 Kudos
Zhanghong_T_
Novice
594 Views

Dear FortranFan,

Thank you very much for your kindly reply. What I need to do is to build the LaGriT (https://github.com/lanl/LaGriT) on Windows 7 64bit +VS2013+Intel Visual Fortran. Do you have any good suggestion to do with less code modification (without using Cygwin)?

Thanks,

Tang Laoya

0 Kudos
FortranFan
Honored Contributor II
594 Views

Zhanghong T. wrote:

..What I need to do is to build the LaGriT (https://github.com/lanl/LaGriT) on Windows 7 64bit +VS2013+Intel Visual Fortran. Do you have any good suggestion to do with less code modification (without using Cygwin)? ..

@Tang Laoya,

You need to contact the author(s) of LaGriT to check whether a version compatible with Windows 7 64bit +VS2013+Intel Visual Fortran is available. 

Please note the code at the GitHub site appears designed to work with gfortran 4.5 which is quite old and it lacks many modern Fortran facilities; accordingly, a code makes use of a lot of NON-STANDARD and possibly NON-PORTABLE aspects, particularly in memory management, and it may be a fool's errand trying to "build the LaGriT (https://github.com/lanl/LaGriT) on Windows 7 64bit +VS2013+Intel Visual Fortran".

Have you tried gfortran 4.5 on Cygwin to first see if you can get the code to work?  That's probably your best option.

0 Kudos
Zhanghong_T_
Novice
594 Views

Dear FortranFan,

Thank you very much for your kindly reply. The authors also suggest to build on Cygwin, but I think it is very difficult to debug the code on Cygwin or Linux environment. 

Now I have successfully build the Windows version under you and Steve's help, but there are still many run time errors during test, I am still trying to modify the code and test.

Thanks,

Tang Laoya

0 Kudos
Reply