Adding Ccalling conventions solves the imbalance problems in the stack. Also change the value [Out]to refto point to the same memory, rather than copy the values. Here is my code
FORTRAN
MODULE TESTING
INTEGER, PARAMETER :: SIZE = 10
TYPE Point
SEQUENCE
REAL*8 :: x(SIZE), y(SIZE) , z(SIZE)
ENDTYPE Point
end module
SUBROUTINE CalcPoint(myPts)
use TESTING
IMPLICIT NONE
TYPE(Point), INTENT(INOUT) :: myPts
INTEGER*4 I
do i = 1,SIZE
myPts%z(i) = myPts%x(i) + myPts%y(i)
enddo
END SUBROUTINE CalcPoint
WITH#
[StructLayout(LayoutKind.Sequential)]
public unsafe struct myPoint
{
public const int size = 10;
public fixed double x[size];
public fixed double y[size];
public fixed double z[size];
public void Initialize(double d1)
{
fixed (double* x_ptr=x, y_ptr=y, z_ptr=z)
{
for (int i=0; i<size; i++)
{
x_ptr[i]=(i+1)*d1;
y_ptr[i]=(i+1)*d1;
z_ptr[i]=0.0;
}
}
}
}
class Program
{
[DllImport(@"FortranDll1.dll", CallingConvention=CallingConvention.Cdecl)]
public unsafe static extern void CalcPoint(ref myPoint t);
unsafe Program()
{
double d1=1.0;
var T=new myPoint();
T.Initialize(d1);
Program.CalcPoint(ref T);
}
static void Main(string[] args)
{
new Program();
}
}
application
To convert a fixed array to a managed array and vice versa, use the following code
public unsafe struct myPoint
{
public const int size=10;
public fixed double x[size];
...
public double[] X
{
get
{
double[] res=new double[size];
fixed (double* ptr=x)
{
for (int i=0; i<size; i++)
{
res[i]=ptr[i];
}
}
return res;
}
set
{
if (value.Length>size) throw new IndexOutOfRangeException();
fixed (double* ptr=x)
{
for (int i=0; i<value.Length; i++)
{
ptr[i]=value[i];
}
}
}
}
}