<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[Approximatrix Forums — Calling Fortran from C#]]></title>
		<link>https://forums.approximatrix.com/viewtopic.php?id=380</link>
		<atom:link href="https://forums.approximatrix.com/extern.php?action=feed&amp;tid=380&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[The most recent posts in Calling Fortran from C#.]]></description>
		<lastBuildDate>Fri, 26 Jun 2015 12:01:10 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[Re: Calling Fortran from C#]]></title>
			<link>https://forums.approximatrix.com/viewtopic.php?pid=2131#p2131</link>
			<description><![CDATA[<p>It depends what you mean by &quot;connected subroutines.&quot;&nbsp; If you&#039;re asking about the case where, for example, your Fortran subroutine calls additional Fortran subroutines <em>in the same DLL</em>, then there really isn&#039;t an issue.&nbsp; Let&#039;s assume the ridiculous case where our <em>timestwo</em> subroutine will actually call a Fortran function to determine the value of 2 in a separate module:</p><div class="codebox"><pre><code>module numbers
contains
    pure function twovalue()
    implicit none
        twovalue = 1.0 + 1.0
    end function twovalue
end module numbers

subroutine timestwo(x, n)
use iso_c_binding
use numbers
implicit none
!GCC$ ATTRIBUTES dllexport, stdcall :: timestwo

real(kind=c_double), intent(inout), dimension(n)::x
integer(kind=c_int), value::n

    x = twovalue()*x

end subroutine timestwo</code></pre></div><p>So when Fortran calls Fortran in the same DLL, there really isn&#039;t anything the programmer has to do to allow this to proceed.&nbsp; The Fortran compiler knows how to call Fortran already.&nbsp; The interface in the C# code remains the same because it doesn&#039;t need to know about our new function, <em>twovalue</em>.</p><p>Things can get mildly more complex if you&#039;re calling a Fortran subroutine in another DLL, but not substantially more complex.&nbsp; </p><p>Does that answer your question?</p>]]></description>
			<author><![CDATA[null@example.com (jeff)]]></author>
			<pubDate>Fri, 26 Jun 2015 12:01:10 +0000</pubDate>
			<guid>https://forums.approximatrix.com/viewtopic.php?pid=2131#p2131</guid>
		</item>
		<item>
			<title><![CDATA[Re: Calling Fortran from C#]]></title>
			<link>https://forums.approximatrix.com/viewtopic.php?pid=2130#p2130</link>
			<description><![CDATA[<p>What do we do for the case of several connected subroutines ?</p>]]></description>
			<author><![CDATA[null@example.com (mahdi_kh8)]]></author>
			<pubDate>Thu, 25 Jun 2015 23:27:27 +0000</pubDate>
			<guid>https://forums.approximatrix.com/viewtopic.php?pid=2130#p2130</guid>
		</item>
		<item>
			<title><![CDATA[Calling Fortran from C#]]></title>
			<link>https://forums.approximatrix.com/viewtopic.php?pid=1556#p1556</link>
			<description><![CDATA[<p>I recently received a request from a user to provide an example of calling Fortran code from a C# program.&nbsp; This procedure is similar to calling Fortran with modern Visual Basic implementations.&nbsp; For this example, we can work with a 32-bit example.&nbsp; Starting with a simple Fortran subroutine:</p><div class="codebox"><pre><code>subroutine timestwo(x, n)
use iso_c_binding
implicit none
!GCC$ ATTRIBUTES dllexport, stdcall :: timestwo

real(kind=c_double), intent(inout), dimension(n)::x
integer(kind=c_int), value::n

    x = 2*x

end subroutine timestwo</code></pre></div><p>In the Fortran code, the subroutine&nbsp; has two attributes assigned, <em>dllexport</em> and <em>stdcall</em>.&nbsp; The former instructs the compiler that this subroutine will be a public DLL function, and the latter specifies the <a href="http://en.wikipedia.org/wiki/X86_calling_conventions">calling convention</a>.&nbsp; This code can be compiled as a 32-bit &quot;Shared Library&quot; project in Simply Fortran.</p><p>The C# code is relatively straightforward as well:</p><div class="codebox"><pre><code>using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace callf
{
    class Program
    {
        [DllImport(&quot;timestwo.dll&quot;, EntryPoint=@&quot;timestwo@8&quot;, CallingConvention=CallingConvention.StdCall)]
        static extern void timestwo(double[] x, int n);

        static void Main(string[] args)
        {
            double[] values = new double[] { 1.0, 3.0, 5.0, 7.0, 9.0 };
            timestwo(values, values.Length);
            foreach(double x in values) {
                System.Console.WriteLine(x);
            }
            
            System.Console.ReadKey();
        }
    }
}</code></pre></div><p>The oddest part is the &quot;DllImport&quot; statement.&nbsp; In this example, we need to specify two extra bits of information to our &quot;DllImport&quot; statement in order to call our &quot;timestwo&quot; subroutine. First, we need to specify the <em>decorated</em> name of the DLL function.&nbsp; If one opens the resultant DLL compiled with Simply Fortran, the editor will list functions in the DLL, once of which will appear similar to:</p><div class="codebox"><pre><code>66781460 T _timestwo@8 </code></pre></div><p>The &quot;EntryPoint&quot; argument to &quot;DllImport&quot; needs to reflect part of the decoration, namely the &quot;@8&quot; portion.&nbsp; Much of the confusion surrounding decorations will actually disappear if a 64-bit DLL is used instead.</p><p>The above code will actually run fine as long as the Fortran DLL is in a proper directory.&nbsp; For simplicity, it should be located in the same directory as the C# executable itself.</p><p>This post is just a simple example of calling Fortran from C#.</p>]]></description>
			<author><![CDATA[null@example.com (jeff)]]></author>
			<pubDate>Thu, 16 Oct 2014 12:55:42 +0000</pubDate>
			<guid>https://forums.approximatrix.com/viewtopic.php?pid=1556#p1556</guid>
		</item>
	</channel>
</rss>
