- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I hope You can help me.
I would like to use this Fortran subroutine:
SUBROUTINE AKIMA (N,XI,YI,I1,X,Y)
!
!DEC$ ATTRIBUTES DLLEXPORT :: Akima
!DEC$ ATTRIBUTES VALUE :: N
!DEC$ ATTRIBUTES VALUE :: X
INTEGER IN, I1
REAL X,XI(1),YI(1),Y(3)
...
END
In C# I use this definition.
[DllImport("FortLib.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void akima(
int n,
[MarshalAs(UnmanagedType.LPArray)] double[] xi,
[MarshalAs(UnmanagedType.LPArray)] double[] yi,
ref int index,
double x,
[MarshalAs(UnmanagedType.LPArray)] double[] y);
1) I get an error like this
System.AccessViolationException
HResult=0x80004003
Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Source=<Cannot evaluate the exception source>
StackTrace:
<Cannot evaluate the exception stack trace>
2) How to do this with 64Bit. I works only with 32 Bit.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I see other problems. On Windows, where this is obviously being run, the Fortran routine name will be AKIMA in uppercase, but the C# name is akima and C# is case-sensitive.
The use of (1) as an array dimension is an old F66 trick back before the days of array bounds checking. The correct way to declare such arrays nowadays is ( * ).
May I suggest the following rewrite?
SUBROUTINE AKIMA (N,XI,YI,I1,X,Y) BIND(C)
USE, INTRINSIC :: ISO_C_BINDING
!
!DEC$ ATTRIBUTES DLLEXPORT :: AKIMA
INTEGER(C_INT), VALUE, INTENT(IN) :: N
REAL_C_DOUBLE), INTENT(INOUT) :: XI(*), YI(*)
INTEGER(C_INT), VALUE, INTENT(IN) :: I1
REAL(C_DOUBLE), VALUE, INTENT(IN) :: X
REAL(C_DOUBLE), INTENT(INOUT) :: Y(3)
...
END
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am not sure this is the only problem (I prefer to use the standard features of Fortran rather than compiler directives), but you pass in an array of double-precision reals, whereas the Fortran routine expects single-precision reals.
Also, the declaration of XI and YI looks like this is old code - or does the routine really only use the first element from both arrays?
Any idea if the Fortran routine does anything at all or does it crash right away?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I see other problems. On Windows, where this is obviously being run, the Fortran routine name will be AKIMA in uppercase, but the C# name is akima and C# is case-sensitive.
The use of (1) as an array dimension is an old F66 trick back before the days of array bounds checking. The correct way to declare such arrays nowadays is ( * ).
May I suggest the following rewrite?
SUBROUTINE AKIMA (N,XI,YI,I1,X,Y) BIND(C)
USE, INTRINSIC :: ISO_C_BINDING
!
!DEC$ ATTRIBUTES DLLEXPORT :: AKIMA
INTEGER(C_INT), VALUE, INTENT(IN) :: N
REAL_C_DOUBLE), INTENT(INOUT) :: XI(*), YI(*)
INTEGER(C_INT), VALUE, INTENT(IN) :: I1
REAL(C_DOUBLE), VALUE, INTENT(IN) :: X
REAL(C_DOUBLE), INTENT(INOUT) :: Y(3)
...
END
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Whenever I need a new C# to Fortran I start here, I just checked it - it is still working.
Your biggest problem is not Fortran it is the frequent C# updates and SDK changes.
Good luck.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes it is code from the eighties, I will modernize it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The advice by @Steve_Lionel is something you may want to closely consider.
Also, see this thread: https://community.intel.com/t5/Intel-Fortran-Compiler/Passing-2D-array-to-C-app-results-in-memory-access-violation/m-p/1131561/highlight/true#M134440
The above gives you a fully worked out example of a somewhat more involved case of a rank-2 array of a struct datatype that will function in a 64-target or 32-bit without any code changes. You can consider applying the learnings and the example toward your situation.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page