Skip to content

Commit f7d348e

Browse files
committed
add c_f_pointer example
1 parent c2981ce commit f7d348e

File tree

7 files changed

+69
-8
lines changed

7 files changed

+69
-8
lines changed

src/cxx/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ add_executable(cxx_fortran_vector vector_main.cxx)
1919
target_link_libraries(cxx_fortran_vector PRIVATE vector_fortran)
2020
add_test(NAME C++_Fortran_vector COMMAND cxx_fortran_vector)
2121

22+
add_executable(cxx_fortran_pointer pointer_main.cxx)
23+
target_link_libraries(cxx_fortran_pointer PRIVATE pointer_fortran)
24+
add_test(NAME C++_Fortran_pointer COMMAND cxx_fortran_pointer)
25+
2226
add_executable(cxx_fortran_error error_main.cxx)
2327
target_link_libraries(cxx_fortran_error PRIVATE error_fortran)
2428
# LINKER_LANGUAGE option is necessary for ifort at least

src/cxx/pointer_main.cxx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#include <iostream>
2+
#include <vector>
3+
4+
extern "C" void point23(float [], float [], size_t*);
5+
6+
7+
int main()
8+
{
9+
10+
std::vector<float> a = {0, 1, 2};
11+
auto N = a.size();
12+
std::vector<float> b(2);
13+
14+
point23(&a.front(), &b.front(), &N);
15+
16+
if (b[0] != a[1] || b[1] != a[2]){
17+
std::cerr << "value " << b[0] << "!=" << a[1] << " or " << b[1] << "!=" << a[2] << std::endl;
18+
return EXIT_FAILURE;
19+
}
20+
21+
std::cout << "OK: C++ to Fortran pointer" << std::endl;
22+
return EXIT_SUCCESS;
23+
}

src/fortran/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ add_library(vector_fortran OBJECT vector_lib.f90)
22

33
add_library(error_fortran OBJECT error_lib.f90)
44

5+
add_library(pointer_fortran OBJECT pointer_lib.f90)
6+
57
add_library(struct_fortran OBJECT struct_lib.f90)
68

79
add_library(submodule_fortran OBJECT module.f90 submodule.f90)

src/fortran/meson.build

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ vector_fortran = library('vector_fortran', 'vector_lib.f90')
22

33
error_fortran = library('error_fortran', 'error_lib.f90')
44

5-
struct_fortran = library('struct_fortran',
6-
sources: 'struct_lib.f90'
7-
)
5+
pointer_fortran = library('pointer_fortran', 'pointer_lib.f90')
6+
7+
struct_fortran = library('struct_fortran', 'struct_lib.f90')
88

99
submodule_fortran = library('submodule',
1010
sources: ['module.f90', 'submodule.f90']

src/fortran/pointer_lib.f90

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
!! This example is overly complicated way to do this task,
2+
!! but it's just to show how c_f_pointer() can work, although it would normally be for more advanced
3+
!! use cases as this task could be done like vector_lib.f90.
4+
module p
5+
6+
use, intrinsic :: iso_c_binding, only : C_FLOAT, C_SIZE_T, C_PTR, c_f_pointer, c_associated
7+
implicit none (type, external)
8+
9+
contains
10+
11+
subroutine point23(p1, b, N) bind(C)
12+
13+
type(C_PTR), value, intent(in) :: p1
14+
real(C_FLOAT), intent(out) :: b(2)
15+
integer(C_SIZE_T), intent(in) :: N
16+
17+
real(C_FLOAT), pointer :: D(:)
18+
19+
call c_f_pointer(p1, D, [N])
20+
21+
if(.not. C_associated(p1)) error stop "input pointer not C associated"
22+
if(.not. associated(D)) error stop "data array pointer not associated"
23+
24+
B = D(2:3)
25+
26+
end subroutine point23
27+
28+
end module p

src/fortran/vector_main.f90

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
program call_c
2-
!! Demonstrate Fortran calling C or C++.
3-
!!
4-
!! Normally BIND(C) should be used after the function name in the interface block,
5-
!! rather than postpending underscore(s).
1+
program vector
62

73
use, intrinsic :: iso_c_binding, only: c_int
84
implicit none (type, external)

src/meson.build

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,11 @@ link_language: 'fortran'
6868
test('C++ Fortran struct', cxx_fortran_struct,
6969
timeout: 5
7070
)
71+
72+
cxx_fortran_pointer = executable('cxx_fortran_pointer',
73+
sources: files('cxx/pointer_main.cxx'),
74+
link_with: pointer_fortran
75+
)
76+
test('C++ Fortran pointer', cxx_fortran_pointer,
77+
timeout: 5
78+
)

0 commit comments

Comments
 (0)