Skip to content

Commit 167be77

Browse files
committed
add opaque C++ => Fortran example
1 parent c656e96 commit 167be77

File tree

4 files changed

+85
-0
lines changed

4 files changed

+85
-0
lines changed

src/cxx/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ target_include_directories(struct_cxx PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../c)
66
add_library(error_cxx OBJECT error_lib.cxx)
77

88
# -- C++ calling Fortran
9+
add_executable(cpp_opaque opaque_main.cxx)
10+
target_link_libraries(cpp_opaque PRIVATE opaque_fortran)
11+
add_test(NAME C++_Fortran_opaque COMMAND cpp_opaque)
12+
913
add_executable(cpp_poly_fcn poly_fcn_main.cpp)
1014
target_link_libraries(cpp_poly_fcn PRIVATE poly_fcn_fortran)
1115
add_test(NAME C++_Fortran_poly_fcn COMMAND cpp_poly_fcn)

src/cxx/opaque_main.cxx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// passing a Fortran-only type to/from C++ where only Fortran operates on opaque type
2+
#include <iostream>
3+
4+
extern "C" void init_opaque_C(void**);
5+
6+
extern "C" void use_opaque_C(void**);
7+
8+
int main(){
9+
10+
void* myf;
11+
12+
init_opaque_C(&myf);
13+
14+
use_opaque_C(&myf);
15+
16+
std::cout << "OK: opaque" << std::endl;
17+
18+
return EXIT_SUCCESS;
19+
}

src/fortran/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
add_library(bool_fortran bool_lib.f90)
22

3+
add_library(opaque_fortran opaque_lib.f90)
4+
35
add_library(vector_fortran OBJECT vector_lib.f90)
46

57
add_library(error_fortran OBJECT error_lib.f90)

src/fortran/opaque_lib.f90

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
module opaque
2+
3+
use, intrinsic :: iso_c_binding, only : C_PTR, c_loc, c_f_pointer
4+
5+
implicit none (type, external)
6+
7+
type :: mytype
8+
integer :: secret
9+
end type mytype
10+
11+
contains
12+
13+
subroutine init_opaque(my)
14+
15+
type(mytype), intent(out) :: my
16+
17+
my%secret = 42
18+
19+
end subroutine init_opaque
20+
21+
22+
subroutine use_opaque(my)
23+
24+
type(mytype), intent(in) :: my
25+
26+
if (my%secret /= 42) error stop "opaque not initialized"
27+
28+
end subroutine use_opaque
29+
30+
!> C shims
31+
32+
subroutine init_opaque_C(myC) bind(C, name="init_opaque_C")
33+
34+
type(C_PTR), intent(out) :: myC
35+
36+
type(mytype), pointer :: my
37+
38+
allocate(my)
39+
!! Note: allocate is necessary or heap error results
40+
myC = c_loc(my)
41+
42+
call init_opaque(my)
43+
44+
! print *, "Fortran:init_opaque_C: my%secret=", my%secret
45+
46+
end subroutine init_opaque_C
47+
48+
49+
subroutine use_opaque_C(myC) bind(C, name="use_opaque_C")
50+
51+
type(C_PTR), intent(in) :: myC
52+
53+
type(mytype), pointer :: my
54+
55+
call c_f_pointer(myC, my)
56+
call use_opaque(my)
57+
58+
end subroutine use_opaque_C
59+
60+
end module opaque

0 commit comments

Comments
 (0)