Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

How to call a C# DLL / CSharp DLL in FORTRAN ?

Carsten_A_
Beginner
1,470 Views

Hello everbody,

I am working on my master thesis. The final goal is to implement a UMAT in ABAQUS.

My adviser will write a DLL in C#. My first step will be to import that DLL in FORTRAN. I found a lot of examples to import FORTRAN DLLs in C# but not the other way around. Is it possible to do this without a wrapper in C++? found here:

https://software.intel.com/en-us/forums/topic/287351

Does anybody have an example for me? I do not have many experience in programming. Therefore, it might be good for me to get a realy short one. Maybe a double 2D-array [,] from C# to FORTRAN (real(8)).

Thx a lot in advance!

0 Kudos
1 Solution
thomas_boehme
New Contributor II
1,470 Views

There are two options that I know to call C# directly:

First and recommended:

Use "Unmanaged Exports" by R. Giesecke (https://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports or by Nuget). It's a small open source tool that allows you to make your .NET methods or functions available to native code. 

Basically, you need to add the [DllExport] attribute to the functions you want to export and the tool will do all that is necessary on build. These exported methods can then be called in the same way as C functions.

It works great for us(also for other languages than Fortran) and is really simple to use. Of course, you still need to figure out all the details of proper argument passing, which can be a bit tricky for character strings are special array formats, but it possible.

Second method (as already written by FortranFan, but not recommended by me due to performance and difficulty in automatization):

Make your .NET functions COM visible and use the Fortran Module Wizard to create a COM wrapper and use this to call the functions.

 

I hope this helps. If you need a concrete example, please let me know. I could try to write a small example, but it will likely take me a day or two.

Best regards,

Thomas

View solution in original post

0 Kudos
4 Replies
Steven_L_Intel1
Employee
1,470 Views

Yes, you can call a Fortran DLL directly. As with all mixed-language calls you have to make sure you get the argument types and calling convention right.

Here's an example I have lying around that illustrates how you declare things in C#. I note looking at this that the string lengths need to be "size_t" integers, not int, but you'll get the idea.

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

namespace CsharpCallsFortran
{
    class Program
    {
        [DllImport(@"FortranDLL.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern void FortranDLL(
            [MarshalAs(UnmanagedType.R4)]System.Single r1,
            [MarshalAs(UnmanagedType.R4)]out System.Single num,
            [MarshalAs(UnmanagedType.LPStr)] System.Text.StringBuilder nnn,
            [MarshalAs(UnmanagedType.LPArray)] int[] arr,
            [MarshalAs(UnmanagedType.I4)] int aLen,
            [MarshalAs(UnmanagedType.LPStr)] System.Text.StringBuilder outstr,
            [MarshalAs(UnmanagedType.I4)]int len,
            [MarshalAs(UnmanagedType.I4)] int outlen);
        [STAThread]
        static void Main(string[] args)
        {
            System.Single r1 = 489.75F;
            System.Single num = 0F;
            System.Text.StringBuilder nnn = new System.Text.StringBuilder("abbccddddddd");
            System.Text.StringBuilder outstring = new System.Text.StringBuilder("                ");
            int len = nnn.Length;
            int[] arrYY = new int[9];
            int aL = 5;
            FortranDLL(r1, out num, nnn, arrYY, aL, outstring, len, 12);
            Console.WriteLine(num);
            Console.ReadLine();

        }
    }
}

When passing multidimensional arrays, you need to be careful about memory layout. I don't know how C# does it, but C two-dimensional arrays are really "arrays of pointers to arrays", not the same as a Fortran 2-dimensional array.

0 Kudos
FortranFan
Honored Contributor III
1,470 Views

Steve Lionel (Intel) wrote:

Yes, you can call a Fortran DLL directly. As with all mixed-language calls you have to make sure you get the argument types and calling convention right.

...

Steve,

OP talks about calling C# DLL from Fortran, not the other way around.

Carsten,

Steve's point, "As with all mixed-language calls you have to make sure you get the argument types and calling convention right." is quite valid. 

However, for the direction you want to take i.e., calling Microsoft's "managed code" in the form of C# DLL from "unmanaged" side i.e., Fortran, you've two options:

  1. Use C++ wrapper layer similar to the link provided by Tao Y. in your duplicate posting on this forum or
  2. Use Intel Fortran Module Wizard with your C# DLL to create a Fortran wrapper layer that you can then use from your Fortran program.  With this option, you may need to make sure your C# DLL is set up to use "COM Interop" and the "exposed" methods and properties in your C# code are COM-compatible as otherwise, some of the data (especially strings) may not interoperate.

 

 

0 Kudos
Steven_L_Intel1
Employee
1,470 Views

Ah, I missed that - thanks.

0 Kudos
thomas_boehme
New Contributor II
1,471 Views

There are two options that I know to call C# directly:

First and recommended:

Use "Unmanaged Exports" by R. Giesecke (https://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports or by Nuget). It's a small open source tool that allows you to make your .NET methods or functions available to native code. 

Basically, you need to add the [DllExport] attribute to the functions you want to export and the tool will do all that is necessary on build. These exported methods can then be called in the same way as C functions.

It works great for us(also for other languages than Fortran) and is really simple to use. Of course, you still need to figure out all the details of proper argument passing, which can be a bit tricky for character strings are special array formats, but it possible.

Second method (as already written by FortranFan, but not recommended by me due to performance and difficulty in automatization):

Make your .NET functions COM visible and use the Fortran Module Wizard to create a COM wrapper and use this to call the functions.

 

I hope this helps. If you need a concrete example, please let me know. I could try to write a small example, but it will likely take me a day or two.

Best regards,

Thomas

0 Kudos
Reply