Here's a version that uses obj-c shim
// ----------------
// BridgingHeader.h
#include "Shim.h"
// ----------------
// Shim.h
#ifndef ShimH
#define ShimH
#import <Foundation/Foundation.h>
#import <inttypes.h>
NS_ASSUME_NONNULL_BEGIN
typedef struct {
int32_t x, y, z;
} Int1D;
typedef struct {
int64_t x, y, z;
} Long1D;
typedef struct {
double x, y, z;
} Real1D;
typedef struct {
Int1D a, b;
} Int2D;
typedef struct {
Long1D a, b;
} Long2D;
typedef struct {
Real1D a, b;
} Real2D;
void objcTestInterface(
char cIn, char* cOut,
int32_t intIn, int32_t* intOut,
int64_t longIn, int64_t* longOut,
double realIn, double* realOut,
NSString* strIn, NSString* __nonnull * __nonnull strOut,
Int1D int1DIn, Int1D* int1DOut,
Long1D long1DIn, Long1D* long1DOut,
Real1D real1DIn, Real1D* real1DOut,
Int2D int2DIn, Int2D* int2DOut,
Long2D long2DIn, Long2D* long2DOut,
Real2D real2DIn, Real2D* real2DOut
);
NS_ASSUME_NONNULL_END
#endif
// ----------------
// Shim.m
#import "Shim.h"
typedef int64_t __int64;
extern void TestInterface(char cIn, char* cOut,
int intIn, int* intOut,
__int64 longIn, __int64* longOut,
double realIn, double* realOut,
char strIn[512], char strOut[512],
int int1DIn[3], int int1DOut[3],
__int64 long1DIn[3], __int64 long1DOut[3],
double real1DIn[3], double real1DOut[3],
int int2DIn[2][3], int int2DOut[2][3],
__int64 long2DIn[2][3], __int64 long2DOut[2][3],
double real2DIn[2][3], double real2DOut[2][3]);
void objcTestInterface(
char cIn, char* __nonnull cOut,
int32_t intIn, int32_t* __nonnull intOut,
int64_t longIn, int64_t* __nonnull longOut,
double realIn, double* __nonnull realOut,
NSString* __nonnull strIn, NSString* __nonnull * __nonnull strOut,
Int1D int1DIn, Int1D* __nonnull int1DOut,
Long1D long1DIn, Long1D* __nonnull long1DOut,
Real1D real1DIn, Real1D* __nonnull real1DOut,
Int2D int2DIn, Int2D* __nonnull int2DOut,
Long2D long2DIn, Long2D* __nonnull long2DOut,
Real2D real2DIn, Real2D* __nonnull real2DOut
)
{
int int2DInValue[2][3] = {
{ int2DIn.a.x, int2DIn.a.y, int2DIn.a.z },
{ int2DIn.b.x, int2DIn.b.y, int2DIn.b.z }
};
int int2DOutValue[2][3] = {
{ int2DOut->a.x, int2DOut->a.y, int2DOut->a.z },
{ int2DOut->b.x, int2DOut->b.y, int2DOut->b.z }
};
int64_t long2DInValue[2][3] = {
{ long2DIn.a.x, long2DIn.a.y, long2DIn.a.z },
{ long2DIn.b.x, long2DIn.b.y, long2DIn.b.z }
};
int64_t long2DOutValue[2][3] = {
{ long2DOut->a.x, long2DOut->a.y, long2DOut->a.z },
{ long2DOut->b.x, long2DOut->b.y, long2DOut->b.z }
};
double real2DInValue[2][3] = {
{ real2DIn.a.x, real2DIn.a.y, real2DIn.a.z },
{ real2DIn.b.x, real2DIn.b.y, real2DIn.b.z }
};
double real2DOutValue[2][3] = {
{ real2DOut->a.x, real2DOut->a.y, real2DOut->a.z },
{ real2DOut->b.x, real2DOut->b.y, real2DOut->b.z }
};
char strInValue[512] = {};
char strOutValue[512] = {};
[strIn getCString:strInValue maxLength:sizeof(strInValue) - 1 encoding:NSASCIIStringEncoding];
TestInterface(
cIn, cOut,
intIn, intOut,
longIn, longOut,
realIn, realOut,
strInValue, strOutValue,
(int*)&int1DIn, (int*)int1DOut,
(int64_t*)&long1DIn, (int64_t*)long1DOut,
(double*)&real1DIn, (double*)real1DOut,
int2DInValue, int2DOutValue,
long2DInValue, long2DOutValue,
real2DInValue, real2DOutValue
);
int2DOut->a.x = int2DOutValue[0][0];
int2DOut->a.y = int2DOutValue[0][1];
int2DOut->a.z = int2DOutValue[0][2];
int2DOut->b.x = int2DOutValue[1][0];
int2DOut->b.y = int2DOutValue[1][1];
int2DOut->b.z = int2DOutValue[1][2];
long2DOut->a.x = long2DOutValue[0][0];
long2DOut->a.y = long2DOutValue[0][1];
long2DOut->a.z = long2DOutValue[0][2];
long2DOut->b.x = long2DOutValue[1][0];
long2DOut->b.y = long2DOutValue[1][1];
long2DOut->b.z = long2DOutValue[1][2];
real2DOut->a.x = real2DOutValue[0][0];
real2DOut->a.y = real2DOutValue[0][1];
real2DOut->a.z = real2DOutValue[0][2];
real2DOut->b.x = real2DOutValue[1][0];
real2DOut->b.y = real2DOutValue[1][1];
real2DOut->b.z = real2DOutValue[1][2];
*strOut = [[NSString alloc] initWithCString:strOutValue encoding:NSASCIIStringEncoding];
}
// ----------------
// test.swift
var cIn: CChar = 1
var cOut: CChar = 2
var intIn: Int32 = 3
var intOut: Int32 = 4
var longIn: Int64 = 5
var longOut: Int64 = 6
var realIn: Double = 7
var realOut: Double = 8
var strIn: String = "ABC"
var strOut: NSString = ""
var int1DIn: Int1D = .init(x: 9, y: 10, z: 11)
var int1DOut = Int1D()
var long1DIn: Long1D = .init(x: 15, y: 16, z: 17)
var long1DOut = Long1D()
var real1DIn: Real1D = .init(x: 21, y: 22, z: 23)
var real1DOut = Real1D()
var int2DIn: Int2D = .init(a: .init(x: 27, y: 28, z: 29), b: .init(x: 30, y: 31, z: 32))
var int2DOut = Int2D()
var long2DIn: Long2D = .init(a: .init(x: 39, y: 40, z: 41), b: .init(x: 42, y: 43, z: 44))
var long2DOut = Long2D()
var real2DIn: Real2D = .init(a: .init(x: 51, y: 52, z: 53), b: .init(x: 54, y: 55, z: 56))
var real2DOut = Real2D()
objcTestInterface(
cIn, &cOut,
intIn, &intOut,
longIn, &longOut,
realIn, &realOut,
strIn, &strOut,
int1DIn, &int1DOut,
long1DIn, &long1DOut,
real1DIn, &real1DOut,
int2DIn, &int2DIn,
long2DIn, &long2DOut,
real2DIn, &real2DOut
)
Minimally tested and should work. Note that this code makes an assumption that C's int and long are 32 and 64 bits respectively. Also string encoding is assumed ascii (but as you mentioned Fortran - that should be fine). Worth checking what happens to a 512 byte long string (there's no room for the trailing 0 in this case).