Interop
Source: examples/interop/
fortran_library provides CcInfo, enabling bidirectional linking between Fortran and C/C++ targets.
2.A. fortran-calling-c
interop/
├── BUILD.bazel
├── c_math.c
├── c_math.h
└── fortran_calls_c.f90c
#ifndef C_MATH_H
#define C_MATH_H
/**
* Simple C math function for testing C/Fortran interop.
* Adds two double precision numbers.
*
* @param a First number
* @param b Second number
* @return Sum of a and b
*/
double c_add_doubles(double a, double b);
#endif /* C_MATH_H */c
#include "c_math.h"
double c_add_doubles(double a, double b) {
return a + b;
}fortran
program fortran_calls_c
use iso_c_binding, only: c_double
implicit none
! Interface to C function
interface
function c_add_doubles(a, b) bind(c, name="c_add_doubles")
import :: c_double
real(c_double), value :: a, b
real(c_double) :: c_add_doubles
end function c_add_doubles
end interface
! Test variables
real(c_double) :: result
! simple addition
result = c_add_doubles(2.0d0, 3.0d0)
if (abs(result - 5.0d0) > 1.0d-10) then
print *, "FAIL: c_add_doubles(2.0, 3.0) = ", result, " expected 5.0"
else
print *, "PASS: c_add_doubles(2.0, 3.0) = 5.0"
end if
end program fortran_calls_cstarlark
cc_library(
name = "c_math",
srcs = ["c_math.c"],
hdrs = ["c_math.h"],
)
fortran_test(
name = "fortran_calls_c",
srcs = ["fortran_calls_c.f90"],
deps = [":c_math"],
)bash
bazel run //interop:fortran_calls_cPASS: c_add_doubles(2.0, 3.0) = 5.02.B. c-calling-fortran
interop/
├── BUILD.bazel
├── c_calls_fortran.c
└── fortran_math.f90fortran
module fortran_math_mod
use iso_c_binding, only: c_double
implicit none
contains
! Function callable from C
! The bind(c, name="...") attribute ensures C-compatible name mangling
function fortran_square(x) bind(c, name="fortran_square")
real(c_double), value :: x ! value attribute for pass-by-value (C convention)
real(c_double) :: fortran_square
fortran_square = x * x
end function fortran_square
end module fortran_math_modc
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
// use bind(c) to ensure C-compatible name mangling.
extern double fortran_square(double x);
int main(void) {
int errors = 0;
double result1 = fortran_square(5.0);
if (fabs(result1 - 25.0) > 1e-10) {
printf("FAIL: fortran_square(5.0) = %f, expected 25.0\n", result1);
errors++;
} else {
printf("PASS: fortran_square(5.0) = 25.0\n");
}
}starlark
fortran_library(
name = "fortran_math",
srcs = ["fortran_math.f90"],
)
cc_test(
name = "c_calls_fortran",
srcs = ["c_calls_fortran.c"],
deps = [":fortran_math"],
)bash
bazel run //interop:c_calls_fortranPASS: fortran_square(5.0) = 25.0