- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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:
my fortran code:my C code
error message:
Please!!!!
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page