Skip to content

Commit 1dfe272

Browse files
committed
add struct fortran => C,Cxx
1 parent 58eacb5 commit 1dfe272

10 files changed

+147
-13
lines changed

src/CMakeLists.txt

+16-8
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,24 @@ add_subdirectory(cxx)
55
add_subdirectory(fortran)
66

77
# -- Fortran calling C++
8-
add_executable(fortran_call_cxx fortran/math_main.f90)
9-
target_link_libraries(fortran_call_cxx PRIVATE math_cxx)
8+
add_executable(fortran_cxx_math fortran/math_main.f90)
9+
target_link_libraries(fortran_cxx_math PRIVATE math_cxx)
1010
# LINKER_LANGUAGE option is necessary for ifort at least
11-
set_target_properties(fortran_call_cxx PROPERTIES LINKER_LANGUAGE Fortran)
12-
add_test(NAME Fortran_call_C++ COMMAND fortran_call_cxx)
11+
set_target_properties(fortran_cxx_math PROPERTIES LINKER_LANGUAGE Fortran)
12+
add_test(NAME Fortran_C++_math COMMAND fortran_cxx_math)
13+
14+
add_executable(fortran_cxx_struct fortran/struct_main.f90)
15+
target_link_libraries(fortran_cxx_struct PRIVATE struct_cxx)
16+
add_test(NAME Fortran_C++_struct COMMAND fortran_cxx_struct)
1317

1418
# -- Fortran calling C
15-
add_executable(fortran_call_c fortran/math_main.f90)
16-
target_link_libraries(fortran_call_c PRIVATE math_c)
17-
add_test(NAME Fortran_call_C COMMAND fortran_call_c)
19+
add_executable(fortran_c_math fortran/math_main.f90)
20+
target_link_libraries(fortran_c_math PRIVATE math_c)
21+
add_test(NAME Fortran_C_math COMMAND fortran_c_math)
22+
23+
add_executable(fortran_c_struct fortran/struct_main.f90)
24+
target_link_libraries(fortran_c_struct PRIVATE struct_c)
25+
add_test(NAME Fortran_C_struct COMMAND fortran_c_struct)
1826

1927
# -- C calling Fortran
2028
add_executable(c_fortran_error c/error_main.c)
@@ -49,6 +57,6 @@ set_target_properties(cxx_fortran_struct PROPERTIES LINKER_LANGUAGE CXX)
4957
add_test(NAME C++_Fortran_struct COMMAND $<TARGET_FILE:cxx_fortran_struct>)
5058

5159
# -- test wrapup
52-
set_tests_properties(C++_Fortran_math C++_Fortran_error Fortran_call_C Fortran_call_C++ PROPERTIES
60+
set_tests_properties(C++_Fortran_math C++_Fortran_error Fortran_C_math Fortran_C++_math PROPERTIES
5361
TIMEOUT 5
5462
)

src/c/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
add_library(math_c OBJECT math_lib.c)
2+
3+
add_library(struct_c OBJECT struct_lib.c)

src/c/meson.build

+2
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
math_c = library('math_c', 'math_lib.c')
2+
3+
struct_c = library('struct_c', 'struct_lib.c')

src/c/struct_lib.c

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#include <stdbool.h>
2+
#include <string.h>
3+
#include <stdlib.h>
4+
#include <stdio.h>
5+
6+
struct params {
7+
// order and lengths must match in Fortran and C
8+
int my_int;
9+
bool my_bool;
10+
int Lmy_char;
11+
char my_char[1000];
12+
};
13+
14+
void struct_check(struct params);
15+
16+
void struct_check(struct params s) {
17+
18+
if (s.my_int != 123) {
19+
fprintf(stderr, "Error: my_int = %d\n", s.my_int);
20+
exit(EXIT_FAILURE);
21+
}
22+
23+
if (! s.my_bool) {
24+
fprintf(stderr, "Error: my_bool is false\n");
25+
exit(EXIT_FAILURE);
26+
}
27+
28+
if (s.Lmy_char != 5) {
29+
fprintf(stderr, "Error: my_char wrong length %d\n", s.Lmy_char);
30+
exit(EXIT_FAILURE);
31+
}
32+
33+
}

src/cxx/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
add_library(math_cxx OBJECT math_lib.cxx)
2+
3+
add_library(struct_cxx OBJECT struct_lib.cxx)

src/cxx/math_main.cxx

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ int main()
1515

1616
for (auto i=0u; i < x2.size(); i++){
1717
if (x2[i] != 2*x[i]){
18-
fprintf(stderr, "value %d != %d", x2[i], x[i]);
18+
std::cerr << "value " << x2[i] << "!=" << x[i] << std::endl;
1919
return EXIT_FAILURE;
2020
}
2121
}

src/cxx/meson.build

+2
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
math_cxx = library('math_cxx', 'math_lib.cxx')
2+
3+
struct_cxx = library('struct_cxx', 'struct_lib.cxx')

src/cxx/struct_lib.cxx

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#include <iostream>
2+
#include <cstring>
3+
#include <cstdlib>
4+
5+
struct params {
6+
// order and lengths must match in Fortran and C
7+
int my_int;
8+
bool my_bool;
9+
int Lmy_char;
10+
char my_char[1000];
11+
};
12+
13+
void struct_check(struct params);
14+
15+
void struct_check(struct params s) {
16+
17+
if (s.my_int != 123) {
18+
std::cerr << "Error: my_int = " << s.my_int << std::endl;
19+
exit(EXIT_FAILURE);
20+
}
21+
22+
if (! s.my_bool) {
23+
std::cerr << "Error: my_bool is false" << std::endl;
24+
exit(EXIT_FAILURE);
25+
}
26+
27+
if (s.Lmy_char != 5) {
28+
std::cerr << "Error: my_char wrong length " << s.Lmy_char << std::endl;
29+
exit(EXIT_FAILURE);
30+
}
31+
32+
}

src/fortran/struct_main.f90

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
program struct_tx
2+
3+
use, intrinsic :: iso_c_binding, only : c_int, c_bool, c_char, c_null_char
4+
5+
implicit none (type, external)
6+
7+
8+
type, bind(C) :: my_struct
9+
!! order and length must match in Fortran and C
10+
integer(c_int) :: my_int
11+
logical(c_bool) :: my_bool
12+
integer(c_int) :: Lmy_char
13+
character(kind=c_char) :: my_char(1000)
14+
!! character(kind=c_char) in bind(c) type cannot be allocatable. Just have to make it "long enough"
15+
!! or use iso_c_binding.h stuff
16+
17+
end type my_struct
18+
19+
20+
interface
21+
subroutine struct_check(p) bind(C)
22+
import my_struct
23+
type(my_struct), intent(in) :: p
24+
end subroutine struct_check
25+
end interface
26+
27+
28+
type(my_struct) :: s
29+
integer :: i
30+
character(:), allocatable :: my_char
31+
32+
my_char = "Hello"
33+
34+
35+
s%my_int = 123
36+
s%my_bool = .true.
37+
s%Lmy_char = len(my_char)
38+
39+
do i = 1, s%Lmy_char
40+
s%my_char(i) = my_char(i:i)
41+
end do
42+
s%my_char(i+1) = c_null_char
43+
44+
45+
print *, "OK: Fortran => C struct"
46+
end program

src/meson.build

+11-4
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,27 @@ subdir('cxx')
55
subdir('fortran')
66

77
# -- Fortran calling C++
8-
fortran_call_cxx = executable('fortran_call_cxx',
8+
fortran_cxx_math = executable('fortran_call_cxx',
99
sources: files('fortran/math_main.f90'),
1010
link_with: math_cxx,
1111
link_language: 'fortran'
1212
)
13-
test('Fortran call C++', fortran_call_cxx, timeout: 5)
13+
test('Fortran C++ math', fortran_cxx_math, timeout: 5)
1414

1515
# -- Fortran calling C
16-
fortran_call_c = executable('fortran_call_c',
16+
fortran_c_math = executable('fortran_c_math',
1717
sources: files('fortran/math_main.f90'),
1818
link_with: math_c,
1919
link_language: 'fortran'
2020
)
21-
test('Fortran call C', fortran_call_c, timeout: 5)
21+
test('Fortran C math', fortran_c_math, timeout: 5)
22+
23+
fortran_c_struct = executable('fortran_call_c',
24+
sources: files('fortran/struct_main.f90'),
25+
link_with: struct_c,
26+
link_language: 'fortran'
27+
)
28+
test('Fortran C struct', fortran_c_struct, timeout: 5)
2229

2330
# -- C calling Fortran
2431
c_fortran_error = executable('c_fortran_error',

0 commit comments

Comments
 (0)