P/Invoke to Fortran DLL - weird parameters...

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Holger (David) Wagner

    P/Invoke to Fortran DLL - weird parameters...

    Hi all,

    we're currently developing an application in the .NET environment that
    needs to access a DLL implemented in Fortran. There is one procedure
    with about 17 parameters, most of them arrays. After some trial and
    error experiments, we've found out that

    a) the parameters must be ordered by type, i.e. we cannot mix double,
    integers and Strings (char-Arrays) - instead, we first need to put
    all the float[]-Arrays and Int32[]-Arrays, and after that, all the
    byte[]-Arrays
    b) each byte[] parameter but the first must exist twice in our C#
    representation of the DLL procedure ("DllImport. .. public extern
    static void...")
    c) we couldn't pass two-dimensional byte-arrays (byte[][]) representing
    one-dimensional arrays of Strings. Instead, we're serializing these
    two-dimensional arrays to one-dimensional arrays.

    Doing it this way, the parameters get to the DLL as intended, and where
    needed they also get back to our .NET context (in/out) - but we're a
    little puzzled why this is the case...

    Possibly, a) is just an artefact of not paying attention to b) (it may
    be that when each byte[] parameter is given twice, float[] can be given
    in between, however, since the first byte[] parameter must exist only
    once, this is not very probable...)

    Any ideas or pointers to documentation on this behavior? We've found
    some information on p/invoke, but nothing about complex cases as the one
    we are facing. Also, this behavior may be specific to Fortran DLLs...

    kind regards,
    david
    --
    Auch das geht vorüber. (Sufi-Weisheit)

    Holger (David) Wagner Tel: +49 (89) 890 50 962
    Dewetstrasse 1 Mobil: +49 (177) 274 12 45
    D-80807 München Fax: +49 (177) 992741245

  • Nicholas Paldino [.NET/C# MVP]

    #2
    Re: P/Invoke to Fortran DLL - weird parameters...

    David,

    There definitely seems to be something wrong. Can you give the actuall
    declarations (C equivalent) for the functions exported from the DLL? Also,
    what is the calling mechanism for the functions exported from this DLL?

    --
    - Nicholas Paldino [.NET/C# MVP]
    - mvp@spam.guard. caspershouse.co m

    "Holger (David) Wagner" <david@purple-sunshine.de> wrote in message
    news:bmg958$50o $1@svr8.m-online.net...[color=blue]
    > Hi all,
    >
    > we're currently developing an application in the .NET environment that
    > needs to access a DLL implemented in Fortran. There is one procedure
    > with about 17 parameters, most of them arrays. After some trial and
    > error experiments, we've found out that
    >
    > a) the parameters must be ordered by type, i.e. we cannot mix double,
    > integers and Strings (char-Arrays) - instead, we first need to put
    > all the float[]-Arrays and Int32[]-Arrays, and after that, all the
    > byte[]-Arrays
    > b) each byte[] parameter but the first must exist twice in our C#
    > representation of the DLL procedure ("DllImport. .. public extern
    > static void...")
    > c) we couldn't pass two-dimensional byte-arrays (byte[][]) representing
    > one-dimensional arrays of Strings. Instead, we're serializing these
    > two-dimensional arrays to one-dimensional arrays.
    >
    > Doing it this way, the parameters get to the DLL as intended, and where
    > needed they also get back to our .NET context (in/out) - but we're a
    > little puzzled why this is the case...
    >
    > Possibly, a) is just an artefact of not paying attention to b) (it may
    > be that when each byte[] parameter is given twice, float[] can be given
    > in between, however, since the first byte[] parameter must exist only
    > once, this is not very probable...)
    >
    > Any ideas or pointers to documentation on this behavior? We've found
    > some information on p/invoke, but nothing about complex cases as the one
    > we are facing. Also, this behavior may be specific to Fortran DLLs...
    >
    > kind regards,
    > david
    > --
    > Auch das geht vorüber. (Sufi-Weisheit)
    >
    > Holger (David) Wagner Tel: +49 (89) 890 50 962
    > Dewetstrasse 1 Mobil: +49 (177) 274 12 45
    > D-80807 München Fax: +49 (177) 992741245
    >[/color]


    Comment

    • Holger (David) Wagner

      #3
      Re: P/Invoke to Fortran DLL - weird parameters...

      Nicholas Paldino [.NET/C# MVP] wrote:[color=blue]
      > There definitely seems to be something wrong. Can you give the actuall
      > declarations (C equivalent) for the functions exported from the DLL? Also,
      > what is the calling mechanism for the functions exported from this DLL?[/color]

      Unfortunately, I don't have access to the Fortran-Declarations -
      however, we finally fixed the problem(s). One major problem was that
      ..NET automatically adds a parameter to byte[]-Arrays or multidimensiona l
      bytearrays. While in the original Fortran-Signature, these parameters
      (e.g. outParam1) exist only once - the C#-declaration must have
      outParam1 and another outParam1X which is probably used to return the
      length of the array.

      We're ignoring this parameter, but if it's missing in the declaration,
      everything gets messed up (without an error message or exception).

      The float/int problem has "disappeared".. . probably, that was an
      artefact of the problem with the strings.

      What remains is that we cannot use LOGICAL on the Fortran side. We *can*
      send arrays of bool/logical to the DLL - but when we invert the values,
      we get back weird results (e.g. everything becomes true). By using
      integers, we found out that Fortran seems to simply change the sign and
      subtract 1, so 0 becomes -1, 1 becomes -2, 2 becomes -3 and so on...
      seems like Fortran is only interested in the last bit while C#/.NET
      compares with 0. We fixed this by using integers in the Fortran-DLL an
      converting them to logicals 1=true, 0=false.

      The import-statement on the C#/.NET side now looks as follows:

      [DllImport("dllN ame.DLL",
      BestFitMapping= false,
      CallingConventi on=CallingConve ntion.Winapi,
      CharSet=CharSet .Ansi,
      EntryPoint="PRO CEDURENAME",
      ExactSpelling=t rue,
      PreserveSig=tru e,
      SetLastError=fa lse,
      ThrowOnUnmappab leChar=true
      )]
      public extern static void wstksdll(
      [In] float[] inParam1, // REAL (4), 200
      [In] Int32[] inParam2, // INTEGER (4), 21
      [In] float[] inParam3, // REAL (4), 21
      [In, Out] byte[] outParam1, // CHARACTER 34, 40, 34
      [In, Out] Int32 outParam1Length ,// not in Fortran-Signature!!!
      [In, Out] Int32[] outParam2, // INTEGER (4), 40
      [In, Out] float[] outParam3, // REAL (4), 40
      [In, Out] float[] outParam4, // REAL (4), 40
      [In, Out] byte[] outParam5, // CHARACTER 14, 40, 14
      [In, Out] Int32 outParam6, // CHARACTER 34, 20, 34
      [In, Out] Int32[] outParam7, // INTEGER (4), 40
      [In, Out, MarshalAs(Unman agedType.LPArra y,
      ArraySubType=Un managedType.I1)]
      bool[] outParam8, // LOGICAL (4), 40
      [In, Out] byte[] outParam9, // CHARACTER 34, 20, 34
      [In, Out] Int32 outParam9Length ,// CHARACTER 30, 20, 30
      );


      --
      Auch das geht vorüber. (Sufi-Weisheit)

      Holger (David) Wagner Tel: +49 (89) 890 50 962
      Dewetstrasse 1 Mobil: +49 (177) 274 12 45
      D-80807 München Fax: +49 (177) 992741245

      Comment

      • Mattias Sjögren

        #4
        Re: P/Invoke to Fortran DLL - weird parameters...

        Holger,
        [color=blue]
        >Unfortunatel y, I don't have access to the Fortran-Declarations -
        >however, we finally fixed the problem(s). One major problem was that
        >.NET automatically adds a parameter to byte[]-Arrays or multidimensiona l
        >bytearrays. While in the original Fortran-Signature, these parameters
        >(e.g. outParam1) exist only once - the C#-declaration must have
        >outParam1 and another outParam1X which is probably used to return the
        >length of the array.[/color]

        It's good to hear that you got it working. But I can assure you that
        C# or the .NET runtime doesn't magically add parameters like that.

        I don't know enough about Fortran to even guess how it exports
        functions or why your changes made it work, but there certainly aren't
        any hidden parameters being added on the managed side.

        [color=blue]
        >What remains is that we cannot use LOGICAL on the Fortran side. We *can*
        >send arrays of bool/logical to the DLL - but when we invert the values,
        >we get back weird results (e.g. everything becomes true). By using
        >integers, we found out that Fortran seems to simply change the sign and
        >subtract 1, so 0 becomes -1, 1 becomes -2, 2 becomes -3 and so on...[/color]

        That's a binary NOT operation (~ in C#).

        ~0 == -1
        ~2 == -3



        Mattias

        --
        Mattias Sjögren [MVP] mattias @ mvps.org

        Please reply only to the newsgroup.

        Comment

        Working...