2012-11-12 84 views
2

我一直在尝试这个东西2天,不能使它的工作。从FORTRAN 77代码返回值C#

我试图做到这一点的人做同样的事情: - >returning real values from fortran77 dll to c#

,因为他做了,我究竟做了一切。即使在相同的编译器中使用相同的参数进行编译。

但我得到“试图读取或写入受保护的内存,这通常表示其他内存已损坏。”错误。

需要帮助!

这里是我的C#代码:

[DllImport("Lks.dll", 
     CharSet = CharSet.Auto, 
     CallingConvention = CallingConvention.StdCall)] 
    public static extern void DON(
     [MarshalAs(UnmanagedType.R8)] double DAA, 
     [MarshalAs(UnmanagedType.R8)] double DBB, 
     [MarshalAs(UnmanagedType.R8)] double DCC 
     ); 

    static unsafe void Main(string[] args) 
    { 
     //double TIME = 100.0; 
     double DAA = 5.5; 
     double DBB = 7; 
     double DCC = 9; 
     //START(ENERIN, VAL1); 
     DON(DAA, DBB, DCC); 

     Console.Write("val1 = " + DAA); 
     Console.Write("val2 = " + DCC); 
     Debug.WriteLine("VAR = " + DBB.ToString()); 
     Console.Write("Press any key to exit"); 
     Console.ReadKey(false); 
    } 

这里是我的FORTRAN 77代码:

*$pragma aux DON "DON" export parm(value*8, reference, reference) 


    SUBROUTINE DON(DAA,DBB,DCC) 
    REAL*8, DAA,DBB,DCC 
    DBB=DAA+1 
    DCC=DBB+1 
    RETURN 
    END 

一切看起来都是一样的我。所以我认为也许是VS2010的问题。

+0

和你的fortran编译器是...? (可能的原因是通过值传递(C#)/通过引用(Fortran)不匹配) – IanH

+0

此'* $ pragma aux ...'只能由Open Watcom F77编译器理解。 –

回答

0

*$pragma aux ...只有Open Watcom FORTRAN 77编译器才能理解辅助编译指示。任何其他编译器都会将它们忽略为注释。代码示例中编译指示的目的是使​​传递值,并将例程符号的外部名称修复为DON(否则Fortran编译器可能将其重新编译为类似于DON_don__的东西)。其他两个论点仍然是通过引用。问题中的P/Invoke接口将它们全部指定为传递值。您需要添加ref关键字:

[DllImport("Lks.dll", 
      CharSet = CharSet.Auto, 
      CallingConvention = CallingConvention.StdCall)] 
public static extern void DON(
    [MarshalAs(UnmanagedType.R8)] double DAA, 
    [MarshalAs(UnmanagedType.R8)] ref double DBB, 
    [MarshalAs(UnmanagedType.R8)] ref double DCC 
); 

你应该使用任何其它的Fortran编译器不理解OW的编译指示,那么所有参数是通过按引用,因此你需要申请ref所有参数:

[DllImport("Lks.dll", 
      CharSet = CharSet.Auto, 
      CallingConvention = CallingConvention.StdCall)] 
public static extern void DON(
    [MarshalAs(UnmanagedType.R8)] ref double DAA, 
    [MarshalAs(UnmanagedType.R8)] ref double DBB, 
    [MarshalAs(UnmanagedType.R8)] ref double DCC 
); 

请注意可能的调用约定不匹配和符号装饰/损坏。检查你的Fortran编译器的手册。

+0

你太棒了!非常感谢。现在都在工作。 :-) – Roiw

+0

@Roiw,所以你真的使用开放Watcom编译器套件?为什么不在Win32上使用像'gfortran'这样更现代的东西? –

+0

是的!我正在使用Open Watcom。我尝试过gfortran,但它没有IDE,看起来更难以学习。这就是我选择Open Watcom的原因。 – Roiw