【发布时间】:2008-10-23 11:18:40
【问题描述】:
我正在尝试调用从 FORTRAN 代码编译的旧版 dll。我是 Interop 的新手,但我已经阅读了一些关于它的文章,看起来我的案例应该相当简单。
我真正想调用的方法有一个复杂的方法签名,但我什至不能调用这个简单的 GetVersion 方法而不得到受保护的内存冲突。
这是我的 DllImport 代码:
[DllImport("GeoConvert.dll",
EntryPoint="_get_version@4",
CallingConvention=CallingConvention.StdCall)]
public static extern void GetGeoConvertVersion([MarshalAs(UnmanagedType.LPStr, SizeConst=8)]
ref string version);
这是 FORTRAN 代码:
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
这是我失败的单元测试:
[Test]
public void TestGetVersion()
{
string version = "";
LatLonUtils.GetGeoConvertVersion(ref version);
StringAssert.IsNonEmpty(version);
}
这是我收到的错误消息:
System.AccessViolationException
Message: Attempted to read or write protected memory.
This is often an indication that other memory is corrupt.
我尝试过的其他事情:
- 使用默认编组
- 传递 char[] 而不是字符串(改为获取方法签名错误)
【问题讨论】:
-
我对您仍在使用 Microsoft Fortran 编译器感到有些震惊。 (他们最后一个 Win32 Fortran 编译器是在 1994 年,不是吗?)我认识的大多数在 Windows 上开发 Fortran 的人都使用 DEC / Compaq / HP / Intel Visual Fortran 或 MinGW 派生的 gfortran。
-
另一方面,如果二进制代码有效,则没有理由重新编译。这可能是升级的强大动力。
标签: c# .net interop fortran dllimport