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

How to call C++ class in Fortran program

cold_boy
Beginner
1,197 Views

I would like to ask how to call C++ classes in Fortran programs. During operation, the program received signal SIGSEGV:Segmentation fault - invalid memory reference is always reported. I don't know why.

my C++ code:

1.png

my fortran code:2.pngmy C code3.png

error message:

4.png

 

 

Please!!!!

0 Kudos
2 Replies
Steve_Lionel
Honored Contributor III
1,049 Views

You can't. Fortran can call C, or C++ code that looks like C (extern "C" void ....) and only with arguments that the standard says "interoperate" with corresponding C arguments. Classes are not included.

0 Kudos
FortranFan
Honored Contributor III
1,024 Views

@cold_boy ,

See this link for some background and a worked out example.

Your particular issue is likely a different matter as you are already attempting a wrapper with the "extern" clause i.e., one where you yourself are stomping on the memory you allocate and deallocate.

You can study the following simplified example for some clues:

 

#include <stdlib.h>

enum N { N = 3 };

typedef struct _my_struct {
   int num;
   int *array;
} my_struct;

void pointer( int* n, int* x ) {
   *n = (int)N;
   for (int i = 0; i < *n; i++) {
      x[i] = i;
   }
   return;
}
                                                      
my_struct make_array() {
   my_struct tmp;
   tmp.array = (int *)malloc( (int)N*sizeof(int) );
   pointer( &tmp.num, tmp.array );
   // uncomment the following two lines and see what happens!?
   //free(tmp.array);
   //tmp.array = NULL;  
   return tmp;
}

void clean_array( my_struct* a) {
    free( a->array );
    a->array = NULL;  
}
   use, intrinsic :: iso_c_binding, only : c_int, c_ptr, c_f_pointer
   type, bind(C) :: my_struct
      integer(c_int) :: num
      type(c_ptr) :: array
   end type
   interface
      function make_array() result(r) bind(C, name="make_array")
         import :: my_struct
         ! Function result
         type(my_struct) :: r 
      end function
      subroutine clean_array( a ) bind(C, name="clean_array")
         import :: my_struct
         ! Argument list
         type(my_struct), intent(inout) :: a 
      end subroutine 
   end interface
   type(my_struct) :: xyz
   integer(c_int), pointer :: x(:)
   integer :: j
   do j = 1, 3
      xyz = make_array()
      call c_f_pointer( cptr=xyz%array, fptr=x, shape=[ xyz%num ] )
      print *, j, size(x), x
      x => null()
      ! uncomment the following line and see what happens
      !print *, j, xyz%num, xyz%array
      ! recommended: utility to clean memory allocated using C run-time
      call clean_array( xyz )
   end do
end
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>ifx /c /standard-semantics /free p.f
Intel(R) Fortran Compiler for applications running on Intel(R) 64, Version 2023.2.0 Build 20230627
Copyright (C) 1985-2023 Intel Corporation. All rights reserved.


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


C:\temp>p.exe
 1 3 0 1 2
 2 3 0 1 2
 3 3 0 1 2

 

 

0 Kudos
Reply