Skip to content

Commit 2f46e9d

Browse files
committed
Add callback test
1 parent 845b7e6 commit 2f46e9d

File tree

2 files changed

+91
-1
lines changed

2 files changed

+91
-1
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
! File : fortran_callback_runme.F90
2+
3+
#include "fassert.h"
4+
5+
module fortran_callback_mod
6+
use, intrinsic :: ISO_C_BINDING
7+
use ISO_FORTRAN_ENV
8+
implicit none
9+
integer, parameter :: STDOUT = OUTPUT_UNIT
10+
integer(C_INT), save, public :: module_int
11+
contains
12+
13+
function myexp(left, right) bind(C) &
14+
result(fresult)
15+
use, intrinsic :: ISO_C_BINDING
16+
integer(C_INT), intent(in), value :: left
17+
integer(C_INT), intent(in), value :: right
18+
integer(C_INT) :: fresult
19+
20+
fresult = left ** right
21+
end function
22+
23+
function mywrite() bind(C) &
24+
result(fresult)
25+
use, intrinsic :: ISO_C_BINDING
26+
integer(C_INT) :: fresult
27+
! write(STDOUT,*) "Hi there"
28+
fresult = 256_c_int
29+
end function
30+
31+
subroutine store_an_int(i) bind(C)
32+
use, intrinsic :: ISO_C_BINDING
33+
integer(C_INT), value, intent(in) :: i
34+
! write(STDOUT,*) "Got an integer: ", i
35+
module_int = i
36+
end subroutine
37+
38+
end module
39+
40+
program fortran_callback_runme
41+
call test_callback
42+
contains
43+
44+
subroutine test_callback
45+
use fortran_callback
46+
use fortran_callback_mod
47+
integer(C_INT) :: i
48+
procedure(call_binary_cb), pointer :: unused => NULL()
49+
procedure(binary_op), pointer :: bin_op_ptr => NULL()
50+
51+
! Use callbacks with Fortran module pointers
52+
bin_op_ptr => myexp
53+
i = call_binary(myexp, 2, 3)
54+
ASSERT(i == 8)
55+
i = call_things(mywrite)
56+
ASSERT(i == 256)
57+
call also_call_things(store_an_int, 999)
58+
ASSERT(module_int == 999)
59+
60+
! Get a C callback
61+
bin_op_ptr => get_a_callback("mul")
62+
ASSERT(associated(bin_op_ptr))
63+
ASSERT(bin_op_ptr(2, 5) == 10)
64+
65+
bin_op_ptr => get_a_callback("add")
66+
ASSERT(associated(bin_op_ptr))
67+
ASSERT(bin_op_ptr(2, 5) == 7)
68+
69+
bin_op_ptr => get_a_callback("nopenope")
70+
ASSERT(.not. associated(bin_op_ptr))
71+
72+
end subroutine
73+
end program
74+
75+

Examples/test-suite/fortran_callback.i

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ extern "C" {
2727
#endif
2828

2929
int add(int left, int right) { return left + right; }
30-
int mul(int left, int right) { return left - right; }
30+
int mul(int left, int right) { return left * right; }
3131

3232
#ifdef __cplusplus
3333
} // end extern
@@ -39,6 +39,11 @@ int mul(int left, int right) { return left - right; }
3939
// Declare callback signature *and* create function with wrapper
4040
%fortrancallback("%s_cb") call_binary;
4141

42+
%{
43+
#include <string.h>
44+
#include <stdio.h>
45+
%}
46+
4247
%inline %{
4348
#ifdef __cplusplus
4449
extern "C" {
@@ -62,5 +67,15 @@ typedef void (*one_int_cb)(int);
6267
void also_call_things(one_int_cb fptr, int val)
6368
{ return (*fptr)(val); }
6469

70+
binary_op_cb get_a_callback(const char* name) {
71+
if (strcmp(name, "add") == 0) {
72+
return &add;
73+
} if (strcmp(name, "mul") == 0) {
74+
return &mul;
75+
}
76+
printf("Invalid callback name '%s'\n", name);
77+
return NULL;
78+
}
79+
6580
%}
6681

0 commit comments

Comments
 (0)