views:

418

answers:

1

Need help , in passing passing C# string to FORTRAN 77 dll as argument.

FORTRAN 77 code:

*$pragma aux CHARIN "CHARIN" export parm(value)
      SUBROUTINE CHARIN(FCHAR)
C Declarations
      CHARACTER*(*)  FCHAR
C
      PRINT*,FCHAR
C
      RETURN
      END

C# code:

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace ConsoleApplication1
{
    class Program
    {
        [DllImport("fdchar.dll",
            CharSet = CharSet.Auto,
            CallingConvention = CallingConvention.StdCall)]
        static extern void returnDecay(
            [MarshalAs(UnmanagedType.LPStr)]string FCHAR,
            int tint);

        static void Main(string[] args)
        {
            string ccc =  "ABCD"; 
            int tint = 4;

            CHARIN(ccc,tint);
            Console.Write("Press any key to EXIT");
            Console.ReadKey(false);
        }
    }
 }
A: 

From what I'm seeing with my own tests, the Fortran DLL appears to lack the hidden length parameter AND C# isn't sending the string in a format Fortran is expecting. It appears that Fortran 77 needs to be tricked into dereferencing the argument being passed along with being given the character argument length explicitly. The following works with Intel Visual Fortran 10.1 and C# 2.0.

Fortran 77:

C       10        20        30        40        50        60        70
C234567890123456789012345678901234567890123456789012345678901234567890
CDEC$ ATTRIBUTES STDCALL, DLLEXPORT::TEST
       SUBROUTINE TEST ( FCHAR, ILEN )
       CHARACTER*(ILEN) FCHAR(1)
C       
       PRINT *,LEN(FCHAR),FCHAR
C       
       RETURN
       ENDSUBROUTINE TEST

C#:

class Program
{
    [DllImport("F77CSharpDllTest.dll",
        EntryPoint = "test",
        CharSet = CharSet.Auto,
        CallingConvention = CallingConvention.StdCall)]
    static extern void Test(
        [MarshalAs(UnmanagedType.LPStr)] string FCHAR,
        int FCHAR_length);

    static void Main(string[] args)
    {
        string hello = "hello";
        Test(hello, hello.Length);
    }
}
sixlettervariables
thanks i did that
did that fix your problem?
sixlettervariables
no.. it was typo mistake .. it is void in my c# code
Have you tried to use EntryPoint to specify the correct entry point in the DLL? Also, can you paste any errors you are getting?
sixlettervariables
i m not getting any error ... the code should print ABCD on console .. instead it is printing some garbage characteras far as entry point is concerned it is fine ..and has only one entry point
I'm getting a similar thing with IVF 10.1 and C#. Trying to figure out what exactly is getting trashed.
sixlettervariables
ya it works with IVF ..but with F77 it dosnt work ..perhaps somthing it has to do with proper marshling
Did you try changing the Fortran to what I had (or something similar).
sixlettervariables
this syntax works only after fortran95 and plus in fortran 77 i still dont know
and if try to compile exact same code .. it will generate compilor eror