@@ -97,7 +97,7 @@ presents some equivalent concepts and names in the two languages:
97
97
| arithmetic type | intrinsic type |
98
98
| derived type | extended type |
99
99
| function parameters | dummy arguments |
100
- | `constexpr` variable | `parameter` statement |
100
+ | `constexpr` variable | named constant |
101
101
102
102
# # Identifiers
103
103
@@ -178,7 +178,7 @@ module forexample
178
178
private
179
179
interface
180
180
function swigc_fact(farg1) &
181
- bind(C, name="swigc_fact ") &
181
+ bind(C, name="_wrap_fact ") &
182
182
result(fresult)
183
183
use, intrinsic :: ISO_C_BINDING
184
184
integer(C_INT) :: fresult
@@ -557,8 +557,10 @@ constants that are guaranteed to be compatible with C enumerators. Unlike C++,
557
557
all enumerators in Fortran are anonymous.
558
558
559
559
To associate a C enumeration name with the Fortran
560
- generated wrappers, SWIG generates an integer parameter with the C enumeration
561
- name. The enumeration generated from the C code
560
+ generated wrappers, SWIG generates a named constant with the C enumeration
561
+ name whose value is the size of the enum that can then be used analogously to
562
+ ` C_INT` , which specifies the size of the native C integer type.
563
+ The enumeration generated from the C code
562
564
` ` ` c++
563
565
enum MyEnum {
564
566
RED = 0,
@@ -575,7 +577,7 @@ looks like:
575
577
enumerator :: BLUE
576
578
enumerator :: BLACK = -1
577
579
end enum
578
- integer, parameter :: MyEnum = kind(RED)
580
+ integer, parameter, public :: MyEnum = kind(RED)
579
581
` ` `
580
582
581
583
These enumerators are treated as standard C integers in the C wrapper code
@@ -594,9 +596,9 @@ enum MyWeirdEnum {
594
596
becomes
595
597
` ` ` fortran
596
598
integer(C_INT), protected, public, &
597
- bind(C, name="swigc_MyWeirdEnum_FOO ") :: FOO
599
+ bind(C, name="_wrap_MyWeirdEnum_FOO ") :: FOO
598
600
integer(C_INT), protected, public, &
599
- bind(C, name="swigc_MyWeirdEnum_BAR ") :: BAR
601
+ bind(C, name="_wrap_MyWeirdEnum_BAR ") :: BAR
600
602
integer, parameter :: MyWeirdEnum = C_INT
601
603
` ` `
602
604
@@ -606,10 +608,6 @@ enable treatment of a C++ `enum` as a Fortran enumerator, and the
606
608
C integers. See the section on [global constants](#global-constants) for more
607
609
on this directive.
608
610
609
- If an enumeration type has not been defined but is used in a function
610
- signature, a placeholder `SwigUnknownEnum` enumerator will be generated and
611
- used instead.
612
-
613
611
Class-scoped enumerations are prefixed with the class name :
614
612
` ` ` c++
615
613
struct MyStruct {
@@ -638,7 +636,7 @@ becomes
638
636
enum, bind(c)
639
637
enumerator :: Foo_Bar = 0
640
638
end enum
641
- integer, parameter :: Foo = kind(Foo_Bar)
639
+ integer, parameter, public :: Foo = kind(Foo_Bar)
642
640
` ` `
643
641
644
642
and
@@ -655,63 +653,153 @@ becomes
655
653
enum, bind(c)
656
654
enumerator :: Cls_Foo_Bar = 0
657
655
end enum
658
- integer, parameter :: Cls_Foo = kind(Cls_Foo_Bar)
659
- ` ` `
656
+ integer, parameter, public :: Cls_Foo = kind(Cls_Foo_Bar)
657
+ ` ` `
658
+
659
+ # # Constants
660
+
661
+ A constant declaration can be wrapped as a Fortran *named constant*
662
+ (a compile-time value defined by having the `parameter` attribute) or as
663
+ an externally linked data object. Constants can be declared with :
664
+ - the SWIG `%constant` directive,
665
+ - simple `#define` macros,
666
+ - enum values, and
667
+ - ` constexpr` global variables.
668
+ The last item is a SWIG-Fortran extension. For an explanation of this behavior,
669
+ see the "Compatibility note" under "A brief word about const" in the SWIG
670
+ documentation. Note that this list does *not* include global `const` data,
671
+ which is wrapped in the same way as mutable global data (though without the
672
+ setter functions).
673
+
674
+ - Native enum values (enum is marked `%fortranconst` or was determined
675
+ automatically to be native compatible) will become enumerators.
676
+ - Constants marked with `%fortranconst` will be rendered as *named constants*.
677
+ - Non-native enum values become C-bound external constants.
678
+ - Constants marked with `%fortranbindc` also become C-bound external
679
+ constants.
680
+ - All other types will generate `getter` functions that return native Fortran
681
+ types.
682
+
683
+ Some compile-time constants can have definitions that are valid C but invalid
684
+ Fortran. A macro whose definition cannot be parsed by Fortran can have its
685
+ value *replaced* with a simpler expression using the `%fortranconstvalue`
686
+ directive.
660
687
661
- # # Function pointers
688
+ The following example shows the behavior of the various rules above :
689
+ ` ` ` swig
690
+ %fortranconst fortranconst_int_global;
691
+ %fortranconst fortranconst_float_global;
692
+ %constant int fortranconst_int_global = 4;
693
+ %constant float fortranconst_float_global = 1.23f;
694
+
695
+ %fortranbindc constant_int_global;
696
+ %constant int constant_int_global = 4;
697
+ %constant float constant_float_global = 1.23f;
698
+
699
+ %fortranconstvalue(4) MACRO_HEX_INT;
662
700
663
- It is possible to pass function pointers both from C to Fortran and from
664
- Fortran to C using SWIG. Currently, function pointer variables
665
- simply generate opaque `type(C_FUNPTR)` objects, and it is up to the user to
666
- convert to a Fortran procedure pointer using `c_f_procpointer` and an
667
- appropriate interface.
701
+ %inline %{
702
+ #define MACRO_INT 4
703
+ const int extern_const_int = 4;
704
+ #define MACRO_HEX_INT 0x4
705
+ %}
706
+ ` ` `
707
+ will be translated to
708
+ ` ` ` fortran
709
+ integer(C_INT), parameter, public :: fortranconst_int_global = 4_C_INT
710
+ real(C_FLOAT), parameter, public :: fortranconst_float_global = 1.23_C_FLOAT
711
+ integer(C_INT), protected, public, &
712
+ bind(C, name="_wrap_constant_int_global") :: constant_int_global
713
+ real(C_FLOAT), protected, public, &
714
+ bind(C, name="_wrap_constant_float_global") :: constant_float_global
715
+ integer(C_INT), protected, public, &
716
+ bind(C, name="_wrap_MACRO_INT") :: MACRO_INT
717
+ public :: get_extern_const_int
718
+ integer(C_INT), parameter, public :: MACRO_HEX_INT = 4_C_INT
719
+ ` ` `
720
+ The symbols marked as `protected, public, bind(C)` have their values defined in
721
+ the C wrapper code, where *any* valid expression can be parsed. The
722
+ ` get_extern_const_int` wrapper function is a SWIG-generated getter that returns
723
+ the external value.
668
724
669
- Consider the simple C SWIG input :
725
+ String constants without special characters (a backslash or anything that must
726
+ be escaped with a backslash) with a can generally be represented
727
+ exactly in Fortran :
670
728
` ` ` swig
729
+ %fortranconst MSG_STRING;
671
730
%inline %{
672
- typedef int (*BinaryOp)(int, int);
731
+ #define MSG_STRING "This is a string"
732
+ %}
733
+ ` ` `
734
+ will generate
735
+ ` ` ` fortran
736
+ character(kind=C_CHAR, len=*), parameter, public :: MSG_STRING = "This is a string"
737
+ ` ` `
673
738
674
- int do_op(int a, int b, BinaryOp op) {
675
- return (*op)(a, b);
676
- }
739
+ # # Function pointers
677
740
678
- int add(int a, int b) {
679
- return a + b;
680
- }
681
- %}
741
+ It is possible to pass function pointers between C and Fortran using SWIG. When
742
+ wrapping, SWIG will automatically generate `abstract interface` functions and
743
+ subroutines for function pointers that have ISO C-compatible signatures. It
744
+ then uses those interfaces in the wrapper functions as procedure pointers.
682
745
683
- %constant BinaryOp ADD_FP = add;
684
- ` ` `
746
+ These abstract interfaces get default names that are not very pretty, so a
747
+ ` %fortrancallback` feature has been introduced to explicitly generate abstract
748
+ interfaces with a meaningful name and dummy argument names
685
749
686
- This generates a *wrapped* function `add`, which converts integer types and
687
- passes them through SWIG wrapper functions as pointers, and a *function
688
- pointer* `add_fp`. The wrapped function pointer is defined as a constant in the
689
- C wrapper code :
690
- ` ` ` c
691
- SWIGEXPORT SWIGEXTERN BinaryOp const _wrap_ADD_FP = add;
750
+ The following C++ SWIG input :
751
+ ` ` ` swig
752
+ %fortrancallback("%s") binary_op;
753
+ extern "C" {
754
+ int binary_op(int left, int right);
755
+ }
692
756
` ` `
693
- and made accessible through the Fortran wrapper module as
694
- ` ` ` fortran
695
- type(C_FUNPTR), protected, public, &
696
- bind(C, name="_wrap_ADD_FP") :: ADD_FP
757
+ generates the following interface :
758
+ ` ` `
759
+ abstract interface
760
+ function binary_op(left, right) bind(C) &
761
+ result(fresult)
762
+ use, intrinsic :: ISO_C_BINDING
763
+ integer(C_INT), intent(in), value :: left
764
+ integer(C_INT), intent(in), value :: right
765
+ integer(C_INT) :: fresult
766
+ end function
767
+ end interface
697
768
` ` `
698
769
699
- The Fortran code in the "funptr" example demonstrates :
700
- - How to pass the C function pointer to another wrapped function `do_op` that
701
- takes a function pointer,
702
- - How to translate a C function pointer into a Fortran function pointer that
703
- can be called directly (using `c_f_procpointer` and an `abstract interface`),
704
- and
705
- - How to translate a Fortran function into a C function pointer, which can then
706
- be passed to a SWIG-wrapped function.
770
+ This allows C++ functions
771
+ ` ` ` swig
772
+ %inline %{
773
+ typedef int (*binary_op_cb)(int, int);
774
+ int call_binary(binary_op_cb fptr, int left, int right);
775
+ %}
776
+ ` ` `
777
+ to generate Fortran functions that take a procedure as an argument :
778
+ ` ` `
779
+ function call_binary(fptr, left, right) &
780
+ result(swig_result)
781
+ use, intrinsic :: ISO_C_BINDING
782
+ integer(C_INT) :: swig_result
783
+ procedure(binary_op) :: fptr
784
+ integer(C_INT), intent(in) :: left
785
+ integer(C_INT), intent(in) :: right
786
+ ! <snip>
787
+ end function
788
+ ` ` `
707
789
708
- Currently function pointers only work with
709
- user-created C-linkage functions, but we plan to extend
710
- function callbacks so that data can be translated through wrapper functions.
790
+ Note that Fortran ISO C rules require the given procedure to be defined in
791
+ Fortran using the `bind(C)` qualifier, as in this module-level code :
792
+ ` ` ` fortran
793
+ function myexp(left, right) bind(C) &
794
+ result(fresult)
795
+ use, intrinsic :: ISO_C_BINDING
796
+ integer(C_INT), intent(in), value :: left
797
+ integer(C_INT), intent(in), value :: right
798
+ integer(C_INT) :: fresult
711
799
712
- Another planned extension for function pointers is to automatically generate
713
- the necessary *abstract interface* code required by Fortran to interpret the
714
- function pointer. This will allow type safety for wrapped function pointers.
800
+ fresult = left ** right
801
+ end function
802
+ ` ` `
715
803
716
804
# # Handles and other oddities
717
805
@@ -899,58 +987,6 @@ will generate a publicly accessible C-bound variable:
899
987
integer(C_INT), public, bind(C, name="global_counter_c") :: global_counter_c
900
988
` ` `
901
989
902
- # ## Global constants
903
-
904
- Global constant variables (whether declared in C++ headers with `const` or in
905
- a SWIG wrapper with `%constant`) of native types can be wrapped as Fortran
906
- " parameters" (compile-time values), as externally bound constants, or as
907
- wrapper functions that return the value.
908
-
909
- The default behavior is as follows :
910
- - ` %constant` and macro values are wrapped as externally bound values.
911
- - Global constants are wrapped with getter functions.
912
- - A constant can be forced to be a Fortran compile-time constant `parameter`
913
- using the `%fortranconst` directive.
914
- - A macro whose definition cannot be parsed by Fortran can have its value
915
- *replaced* with a simpler expression using the `%fortranconstvalue`
916
- directive.
917
-
918
- The following example shows the behavior of the various rules above :
919
- ` ` ` swig
920
- %fortranconst fortranconst_int_global;
921
- %fortranconst fortranconst_float_global;
922
- %constant int fortranconst_int_global = 4;
923
- %constant float fortranconst_float_global = 1.23f;
924
-
925
- %constant int constant_int_global = 4;
926
- %constant float constant_float_global = 1.23f;
927
-
928
- %fortranconstvalue(4) MACRO_HEX_INT;
929
-
930
- %inline %{
931
- #define MACRO_INT 4
932
- const int extern_const_int = 4;
933
- #define MACRO_HEX_INT 0x4
934
- %}
935
- ` ` `
936
- will be translated to
937
- ` ` ` fortran
938
- public :: get_extern_const_int
939
- integer(C_INT), parameter, public :: fortranconst_int_global = 4_C_INT
940
- real(C_FLOAT), parameter, public :: fortranconst_float_global = 1.23_C_FLOAT
941
- integer(C_INT), protected, public, &
942
- bind(C, name="_wrap_constant_int_global") :: constant_int_global
943
- real(C_FLOAT), protected, public, &
944
- bind(C, name="_wrap_constant_float_global") :: constant_float_global
945
- integer(C_INT), protected, public, &
946
- bind(C, name="_wrap_MACRO_INT") :: MACRO_INT
947
- integer(C_INT), parameter, public :: MACRO_HEX_INT = 4_C_INT
948
- ` ` `
949
- The symbols marked as `protected, public, bind(C)` have their values defined in
950
- the C wrapper code, where *any* valid expression can be parsed. The
951
- ` get_extern_const_int` wrapper function is a SWIG-generated getter that returns
952
- the external value.
953
-
954
990
# # Classes
955
991
956
992
C++ classes are transformed to Fortran *derived types*. These types have
@@ -1941,6 +1977,14 @@ To bind *all* functions as native C interfaces, use
1941
1977
This is often useful when coupled with the `%fortranconst` directive (see
1942
1978
the [enumerations](#enumerations) section).
1943
1979
1980
+ # ## Function pointers and callbacks
1981
+
1982
+ The `%callback` feature is redundant and ignored for `%fortranbindc` types : a
1983
+ valid function pointer to the C function can be obtained simply with the
1984
+ ` c_funptr` intrinsic function. Any `%fortrancallback` directives in the code
1985
+ will still generate abstract interfaces, but they will simply supplement the
1986
+ direct-bound C code
1987
+
1944
1988
# ## Generating C-bound Fortran types from C structs
1945
1989
1946
1990
In certain circumstances, C++ structs can be wrapped natively as Fortran
@@ -2014,7 +2058,7 @@ module thinvec
2014
2058
end type
2015
2059
interface
2016
2060
subroutine swigc_foo(farg1) &
2017
- bind(C, name="swigc_foo ")
2061
+ bind(C, name="_wrap_foo ")
2018
2062
use, intrinsic :: ISO_C_BINDING
2019
2063
import :: SwigArrayWrapper ! Will not compile without this line
2020
2064
type(SwigArrayWrapper) :: farg1
@@ -2066,3 +2110,5 @@ void should_be_wrapped(UnknownType*);
2066
2110
2067
2111
A number of known limitations to the SWIG Fortran module are tracked [on
2068
2112
GitHub](https://github.com/sethrj/swig/issues/59).
2113
+
2114
+ <!-- vim : set tw=79: -->
0 commit comments