<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Approximatrix Forums — Calling Fortran from C#]]></title>
	<link rel="self" href="https://forums.approximatrix.com/extern.php?action=feed&amp;tid=380&amp;type=atom" />
	<updated>2015-06-26T12:01:10Z</updated>
	<generator>PunBB</generator>
	<id>https://forums.approximatrix.com/viewtopic.php?id=380</id>
		<entry>
			<title type="html"><![CDATA[Re: Calling Fortran from C#]]></title>
			<link rel="alternate" href="https://forums.approximatrix.com/viewtopic.php?pid=2131#p2131" />
			<content type="html"><![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>]]></content>
			<author>
				<name><![CDATA[jeff]]></name>
				<uri>https://forums.approximatrix.com/profile.php?id=2</uri>
			</author>
			<updated>2015-06-26T12:01:10Z</updated>
			<id>https://forums.approximatrix.com/viewtopic.php?pid=2131#p2131</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: Calling Fortran from C#]]></title>
			<link rel="alternate" href="https://forums.approximatrix.com/viewtopic.php?pid=2130#p2130" />
			<content type="html"><![CDATA[<p>What do we do for the case of several connected subroutines ?</p>]]></content>
			<author>
				<name><![CDATA[mahdi_kh8]]></name>
				<uri>https://forums.approximatrix.com/profile.php?id=3624</uri>
			</author>
			<updated>2015-06-25T23:27:27Z</updated>
			<id>https://forums.approximatrix.com/viewtopic.php?pid=2130#p2130</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Calling Fortran from C#]]></title>
			<link rel="alternate" href="https://forums.approximatrix.com/viewtopic.php?pid=1556#p1556" />
			<content type="html"><![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>]]></content>
			<author>
				<name><![CDATA[jeff]]></name>
				<uri>https://forums.approximatrix.com/profile.php?id=2</uri>
			</author>
			<updated>2014-10-16T12:55:42Z</updated>
			<id>https://forums.approximatrix.com/viewtopic.php?pid=1556#p1556</id>
		</entry>
</feed>
