0

I am trying to use a Fortran DLL in C# and I have no experience in Fortran. The parts I am having problems are with output arguments of the dll, specifically with characters. In the Fortran code they are defined as:

character*32 JobName
character*(*)  Fname
character*80  Title(2)

Does anyone know the equivalent in C#? All the others are ints so I can deal with them. From reading around, I cant directly use char as it is 8 bytes in C# and 4 in Fortran.

More of the Fortran code is below:

*deck,ResRdBegin
    function ResRdBegin (Nunit, Lunit, Fname, ncFname, Title, JobName, Units, NumDOF, DOF, UserCode, MaxNode, NumNode, MaxElem, NumElem, MaxResultSet,NumResultSet)
    integer ResRdBegin, Nunit, Lunit, ncFname, Units, iTemp(100), NumDOF, DOF(*), UserCode, kbf, NumResultSet, MaxNode, NumNode, MaxElem, NumElem, MaxResultSet, i,j
    character*32 JobName
    character*(*)  Fname
    character*80  Title(2)
Chrism
  • 1
  • 2
  • 2
    Are you trying to convert it to C#, or actually reference the DLL? I'm not sure you can reference a Fortran DLL unless it's wrapped in COM. – Tim Mar 15 '16 at 23:38
  • 1
    An answer to [this question](https://stackoverflow.com/q/33415590) covers two of the cases. The form `character*(*)` gives an assumed length character variable which behaves a little differently from those other two. – francescalus Mar 16 '16 at 09:13
  • Note that just the last one is an array (of length two), the others are just strings, not arrays. More important will be that there are likely to be hidden arguments in the argument list: http://stackoverflow.com/questions/34822683/how-should-multiple-fortran-strings-be-passed-to-c http://stackoverflow.com/questions/8207997/calling-a-fortran-subroutine-from-c The hidden argument contains the length of the string, not the length of the array. – Vladimir F Героям слава Mar 16 '16 at 09:24
  • To say more you will have to sow more. The complete header of the Fortran procedure at least. Including any compiler directives. – Vladimir F Героям слава Mar 16 '16 at 09:28
  • Thanks guys, lots to read through... It will take me a little while. In the meantime I will add a bit more detail. I was a bit vague as the source code is copyrighted, but I am licensed to use the dll. The file is used to read a binary output from some commercial software. This is a link to a blog post where someone has done the same using cpp. Again, my problems come when handling the character types. http://www.padtinc.com/blog/the-focus/reading-ansys-mechanical-rst-c-cpp-part1 – Chrism Mar 16 '16 at 10:37
  • The fortran source i have is very simple and I don't think it has any compiler directives, it starts like: `*deck,ResRdBegin function ResRdBegin (Nunit, Lunit, Fname, ncFname, Title, JobName, x Units, NumDOF, DOF, UserCode, x MaxNode, NumNode, MaxElem, NumElem, x MaxResultSet,NumResultSet)` and then defines the arguments as in the main post. – Chrism Mar 16 '16 at 10:41
  • `*deck,ResRdBegin` doesn't look like Fortran. – Vladimir F Героям слава Mar 16 '16 at 11:20
  • @VladimirF It does to me: fixed form commentary. I imagine the whole code block of that comment is meant to be fixed-form over several lines (looking at the initial `*` and those `x`s that look like being continuation markers). That all means, Chrism, please format the code from your comment into the question if you think it's important: it makes no sense as it is. – francescalus Mar 16 '16 at 20:31
  • Ah I see. Proper formatting is indeed necessary. – Vladimir F Героям слава Mar 16 '16 at 20:51
  • Sorry for the bad formatting, I have just added it to the original post, formatted the same as it is in the code I have. I've just got back from work so will continue to work on it. Thanks for all the help so far. – Chrism Mar 16 '16 at 22:09

1 Answers1

0

You should be able to use char[] (with CharSet.Ansi) in C# to pass in the character arrays to Fortran. For the 2x80 character array, I'd just pass in a single 160 character array. The character*(*) variable has its length defined as an input via the ncFname parameter. Use [In,Out] to specify input and output for the array parameters. Scalars should be passed by ref.

http://www.luckingtechnotes.com/calling-fortran-dll-from-csharp/

The P/Invoke signature should look like this.

[DllImport("binlib.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern int RESRDBEGIN(ref int Nunit, ref int Lunit, [In] char[] Fname, ref int ncFname, [In, Out] char[] Title, [In, Out] char[] JobName,
     ref int Units, ref int NumDOF, [In, Out] int[] DOF, ref int UserCode,
     ref int MaxNode, ref int NumNode, ref int MaxElem, ref int NumElem,
     ref int MaxResultSet, ref int NumResultSet);

I run ANSYS as well. I tested and this method seems to work - returns valid data. However the debugger throws an AccessViolation if you set a breakpoint before the call, so I may be missing something. No issue if a breakpoint is set after the call though.

rybo103
  • 335
  • 2
  • 7
  • Thanks, i've got it working now.... there were a few other issues. VS wants to prefer 32bit by default, the dll was 64bit. The dll references many other dlls. If the program crashes, its seems to lock access to the file. Thanks for all your help! – Chrism Mar 21 '16 at 14:53