In the following I used Robert Giesecke's unmanaged export template to make unmanaged dlls. I tried sucessfully to pass a value from C# to Fortran with following code:
using System;
using System.Collections.Generic;
using System.Text;
using RGiesecke.DllExport;
namespace AddDll
{
class MyAddDll
{
[DllExport("Add", CallingConvention = System.Runtime.InteropServices.CallingConvention.Cdecl)]
public static int Add(int a, int b)
{
return a + b;
}
}
}
On the Fortran side:
MODULE MYEXTERNALS
USE iso_c_binding
INTERFACE
FUNCTION Add(a,b) RESULT(ret) bind(c, name="Add")
USE, intrinsic :: iso_c_binding
INTEGER(c_int), VALUE, intent(in) :: a,b
INTEGER(c_int) :: ret
END FUNCTION
END INTERFACE
END MODULE MYEXTERNALS
PROGRAM CallAdd
USE MYEXTERNALS
IMPLICIT NONE
INTEGER a, b
a = 4
b = 3
PRINT*, 'a + b =', Add(a, b)
PAUSE
END PROGRAM CallAdd
that works fine! Now I would like to pass an array with following code:
using System;
using System.Collections.Generic;
using System.Text;
using RGiesecke.DllExport;
using System.Runtime.InteropServices;
namespace AddDll
{
class MyAddDll
{
[DllExport("Add", CallingConvention = System.Runtime.InteropServices.CallingConvention.Cdecl)]
public static int Add([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] int[] tab, int idx)
{
return tab[idx];
}
}
}
On the Fortran side:
MODULE MYEXTERNALS
USE iso_c_binding
INTERFACE
FUNCTION Add(tab, idx) result(ret) bind(c, name="Add")
USE, intrinsic :: iso_c_binding
INTEGER(c_int), intent(in) :: tab(3)
INTEGER(c_int) :: ret, idx
END FUNCTION
END INTERFACE
END MODULE MYEXTERNALS
PROGRAM CallAdd
USE MYEXTERNALS
IMPLICIT NONE
integer(c_int) :: i
integer(c_int) :: tab(3)
tab(1) = 1
tab(2) = 2
tab(3) = 3
do i=1, 3
PRINT*, Add(tab, i)
end do
PAUSE
END PROGRAM CallAdd
Unfortunately, it gives me an access violation error!
Can anyone help me to fix the problem?