I am trying to call out to a legacy dll compiled from FORTRAN code. I am new to Interop, but I’ve read some articles on it and it seems like my case should be fairly straightforward.
The method I really want to call has a complex method signature, but I can’t even call this simple GetVersion method without getting a protected memory violation.
Here’s my DllImport code:
[DllImport('GeoConvert.dll', EntryPoint='_get_version@4', CallingConvention=CallingConvention.StdCall)] public static extern void GetGeoConvertVersion([MarshalAs(UnmanagedType.LPStr, SizeConst=8)] ref string version);
Here’s the FORTRAN code:
SUBROUTINE GetVer( VRSION ) C !MS$DEFINE MSDLL !MS$IF DEFINED (MSDLL) ENTRY Get_Version (VRSION) !MS$ATTRIBUTES DLLEXPORT,STDCALL :: Get_Version !MS$ATTRIBUTES REFERENCE :: VRSION !MS$ENDIF !MS$UNDEFINE MSDLL C CHARACTER*8 VRSION C VRSION = '1.0a_FhC' C RETURN END
Here’s my unit test that fails:
[Test] public void TestGetVersion() { string version = ''; LatLonUtils.GetGeoConvertVersion(ref version); StringAssert.IsNonEmpty(version); }
Here’s the error message I get:
System.AccessViolationException Message: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Other things I’ve tried:
- Using the default marshalling
- Passing a char[] instead of a string (get method signature errors instead)
OK, I got it to work, the problem was passing by ref. I’m not sure why, but this works:
With this test: