I’ve been confused in the past with wrappers (like in this StackOverflow thread). Typically you find examples of wrapping non-interoperable C/C++ objects in Fortran rather than the other way round. I guess not that many C/C++ developers appreciate the features of modern Fortran.
Btw, in case you are willing to use C++, the C API can be wrapped in a C++ class which has the benefit of automatic lifetime management (RAII) and other C++ goodies like std::span
and the STL:
#include <numeric>
#include <span>
#include "somemodule_wrap.h"
class Sometype {
public:
// Constructor
Sometype(int n) : ptr{ sometype_create(n) } {}
// Destructor
~Sometype() { sometype_free(ptr); }
// Access array member `a`
std::span<double> a() const {
int n; double *a;
a = static_cast<double *>( sometype_a(ptr,&n) );
return { a, (size_t) n };
}
// Retrieve raw pointer to underlying object
void *get() const { return ptr; }
private:
void *ptr{nullptr};
};
void frout(const Sometype& x) {
frout2_wrap( x.get() );
}
The usage becomes simpler than in C and you get to use STL algorithms with the std::span
int main(void)
{
Sometype x{6};
auto a = x.a(); // a is a view (memory owned by x)
// Fill with increasing numbers
std::iota(a.begin(),a.end(),0.0);
frout(x);
return 0;
}