<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[Approximatrix Forums — Fortran DLL for use in Excel VBA - another round of questions]]></title>
		<link>https://forums.approximatrix.com/viewtopic.php?id=366</link>
		<atom:link href="https://forums.approximatrix.com/extern.php?action=feed&amp;tid=366&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[The most recent posts in Fortran DLL for use in Excel VBA - another round of questions.]]></description>
		<lastBuildDate>Mon, 11 Apr 2016 14:27:31 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[Re: Fortran DLL for use in Excel VBA - another round of questions]]></title>
			<link>https://forums.approximatrix.com/viewtopic.php?pid=2460#p2460</link>
			<description><![CDATA[<p>Hi Jeff &amp; Frank, </p><p>I was able to get that to work. Thanks so much for your help!</p><p>Jason</p>]]></description>
			<author><![CDATA[null@example.com (jason_b1975)]]></author>
			<pubDate>Mon, 11 Apr 2016 14:27:31 +0000</pubDate>
			<guid>https://forums.approximatrix.com/viewtopic.php?pid=2460#p2460</guid>
		</item>
		<item>
			<title><![CDATA[Re: Fortran DLL for use in Excel VBA - another round of questions]]></title>
			<link>https://forums.approximatrix.com/viewtopic.php?pid=2453#p2453</link>
			<description><![CDATA[<p>Jason,</p><p>Frank&#039;s VBA call is what really needs to happen.&nbsp; So I have a Fortran subroutine that I wish to call that will modify an array:</p><div class="codebox"><pre><code>subroutine timestwo(x, n) bind(c)
implicit none
!gcc$ attributes stdcall, dllexport::timestwo

    integer, intent(in)::n
    real(kind=8), intent(inout), dimension(n)::x
    
    x = 2.0*x
    
end subroutine timestwo</code></pre></div><p>To call from VBA, the following works for me:</p><div class="codebox"><pre><code>Declare PtrSafe Sub TimesTwo Lib &quot;C:\workspace\example\excel\timestwo.dll&quot; Alias &quot;timestwo&quot; (ByRef x As Double, n As Integer)

Sub Button2_Click()

    Dim x(1 To 10) As Double
    
    For i = 1 To 10
        x(i) = Cells(i, 1)
    Next i
        
    Call TimesTwo(x(1), 10)
    
    For i = 1 To 10
        Cells(i, 2) = x(i)
    Next i

End Sub</code></pre></div><p>A few things to note:</p><p>In VBA, I&#039;m declaring that my Fortran function, <em>timestwo</em>, accepts a scalar double by reference, which may seem contradictory.&nbsp; When I call my subroutine, I am passing the first element of my array only.&nbsp; This procedure works because what we&#039;ve effectively done is passed to Fortran the memory address of the first element of the array.&nbsp; Our Fortran code expects an array, but it is actually receiving an address to the array in reality.&nbsp; Everything actually works because the address of the first element of the array is effectively the address of the array.</p><p>In my example, the second column of my spreadsheet ends up populated with double the values of the first column.</p><p>I should point out that everything here is tested on Windows 7 64-bit using 64-bit Excel 2013.&nbsp; There may be some differences if Excel is in 32-bit mode because the <em>STDCALL</em> decorations will be present.&nbsp; However, the base code should work.</p>]]></description>
			<author><![CDATA[null@example.com (jeff)]]></author>
			<pubDate>Wed, 06 Apr 2016 12:29:46 +0000</pubDate>
			<guid>https://forums.approximatrix.com/viewtopic.php?pid=2453#p2453</guid>
		</item>
		<item>
			<title><![CDATA[Re: Fortran DLL for use in Excel VBA - another round of questions]]></title>
			<link>https://forums.approximatrix.com/viewtopic.php?pid=2450#p2450</link>
			<description><![CDATA[<p>Jason,</p><p>Sorry, I was caught up in a few other things.&nbsp; Frank&#039;s suggestion about passing the first array element <em>ByRef</em> might work, but I&#039;m not sure.&nbsp; I promise to look into it more early next week.</p>]]></description>
			<author><![CDATA[null@example.com (jeff)]]></author>
			<pubDate>Fri, 01 Apr 2016 19:38:07 +0000</pubDate>
			<guid>https://forums.approximatrix.com/viewtopic.php?pid=2450#p2450</guid>
		</item>
		<item>
			<title><![CDATA[Re: Fortran DLL for use in Excel VBA - another round of questions]]></title>
			<link>https://forums.approximatrix.com/viewtopic.php?pid=2449#p2449</link>
			<description><![CDATA[<p>Jason,</p><p>Although it&#039;s been a while since I&#039;ve used VBA, here are a couple of suggestions:</p><p>&#039;--- Set all variables to be declared<br />Option Explicit</p><p>&#039;--- Set array index starting at 1<br />Option Base 1</p><p>&#039;--- To pass an array from VBA to Fortran, you must pass the first element<br />&#039;--- of the array. By default, Visual Basic passes variables by reference, so<br />&#039;--- passing the first element of the array as a scalar will give Fortran the<br />&#039;--- starting address of the variable arrays. <br />&#039;<br />&#039;--- Double in VBA is the same as REAL*8 in Fortran<br />&#039;--- Long in VBA is the same as Integer*3 in Fortran<br />&#039;<br />&#039;--- Call your Fortran subroutine as follows:<br />CALL aArrPbArr( A(1), B(1), C(1), n )</p><p>I hope this is helpful,<br />Frank</p>]]></description>
			<author><![CDATA[null@example.com (drfrank)]]></author>
			<pubDate>Thu, 31 Mar 2016 21:02:42 +0000</pubDate>
			<guid>https://forums.approximatrix.com/viewtopic.php?pid=2449#p2449</guid>
		</item>
		<item>
			<title><![CDATA[Re: Fortran DLL for use in Excel VBA - another round of questions]]></title>
			<link>https://forums.approximatrix.com/viewtopic.php?pid=2447#p2447</link>
			<description><![CDATA[<p>Jeff, </p><p>I&#039;m guessing you haven&#039;t had any luck with this so far. Looks like a wrapper through .Net is in order to get the functionality in VBA.</p><p>Jason</p>]]></description>
			<author><![CDATA[null@example.com (jason_b1975)]]></author>
			<pubDate>Thu, 31 Mar 2016 14:14:04 +0000</pubDate>
			<guid>https://forums.approximatrix.com/viewtopic.php?pid=2447#p2447</guid>
		</item>
		<item>
			<title><![CDATA[Re: Fortran DLL for use in Excel VBA - another round of questions]]></title>
			<link>https://forums.approximatrix.com/viewtopic.php?pid=2425#p2425</link>
			<description><![CDATA[<p>Jeff, </p><p>It does let me compile and run without any ByRef/ByVal directive, but it still behaves as a ByRef - i.e.: the c array still contains all zeros after going through aArrPbArr.</p><p>I wish VBA behaved a bit more like VB/C#.net. I do a lot of stuff in Excel, so unfortunately I have to live with the inadequacies of VBA.</p><p>Thanks, <br />Jason</p>]]></description>
			<author><![CDATA[null@example.com (jason_b1975)]]></author>
			<pubDate>Thu, 10 Mar 2016 18:23:49 +0000</pubDate>
			<guid>https://forums.approximatrix.com/viewtopic.php?pid=2425#p2425</guid>
		</item>
		<item>
			<title><![CDATA[Re: Fortran DLL for use in Excel VBA - another round of questions]]></title>
			<link>https://forums.approximatrix.com/viewtopic.php?pid=2424#p2424</link>
			<description><![CDATA[<p>Jason,</p><p>What happens if you simply don&#039;t include the <strong>ByVal</strong> in front of each argument in the declaration?</p><p>I&#039;ll try using actual VBA to see if I can find a solution.</p>]]></description>
			<author><![CDATA[null@example.com (jeff)]]></author>
			<pubDate>Thu, 10 Mar 2016 17:54:26 +0000</pubDate>
			<guid>https://forums.approximatrix.com/viewtopic.php?pid=2424#p2424</guid>
		</item>
		<item>
			<title><![CDATA[Re: Fortran DLL for use in Excel VBA - another round of questions]]></title>
			<link>https://forums.approximatrix.com/viewtopic.php?pid=2423#p2423</link>
			<description><![CDATA[<p>Jeff, </p><p>Hmm... I might need to use a wrapper through a .net language then. VBA will not permit you to pass arrays ByVal (not even in a Declare Sub). Do you have any other ideas for how to get around that? I don&#039;t tend to think in pointers (aside from whether to use ByRef or ByVal), but maybe telling the Declare Sub that it&#039;s a pointer and then pointing the c() array to that location? (not sure how to even do that.)</p><p>Thanks, <br />Jason</p>]]></description>
			<author><![CDATA[null@example.com (jason_b1975)]]></author>
			<pubDate>Thu, 10 Mar 2016 15:37:56 +0000</pubDate>
			<guid>https://forums.approximatrix.com/viewtopic.php?pid=2423#p2423</guid>
		</item>
		<item>
			<title><![CDATA[Re: Fortran DLL for use in Excel VBA - another round of questions]]></title>
			<link>https://forums.approximatrix.com/viewtopic.php?pid=2422#p2422</link>
			<description><![CDATA[<p>Jason,</p><p>You&#039;re almost correct, but there&#039;s one change you need to make to your declaration of <em>aArrPbArr</em> in VBA that needs to change that might seem illogical.&nbsp; When you pass arrays to Fortran from VBA, you actually want to pass <strong>ByVal</strong> because an array in VBA is just a pointer.&nbsp; When you pass by reference, you&#039;re actually passing a pointer to the array&#039;s starting address rather than just the array&#039;s starting address.&nbsp; Fortran, on the other hand, just expects the array&#039;s starting address. </p><p>If you change your declaration to:</p><div class="codebox"><pre><code>Declare Sub aArrPbArr Lib &quot;callee.dll&quot; Alias &quot;aarrpbarr@16&quot; (ByVal a() As Double, ByVal b() As Double, ByVal c() As Double, ByRef n As Integer)</code></pre></div><p>It should work.&nbsp; I tested it in VB.Net, and everything ran smoothly (except it didn&#039;t like your VB array dimensions starting at 1, but that&#039;s not the problem you were having).</p>]]></description>
			<author><![CDATA[null@example.com (jeff)]]></author>
			<pubDate>Thu, 10 Mar 2016 13:34:59 +0000</pubDate>
			<guid>https://forums.approximatrix.com/viewtopic.php?pid=2422#p2422</guid>
		</item>
		<item>
			<title><![CDATA[Re: Fortran DLL for use in Excel VBA - another round of questions]]></title>
			<link>https://forums.approximatrix.com/viewtopic.php?pid=2417#p2417</link>
			<description><![CDATA[<p>I have tried this out and gotten the apb example to work just fine as it is (mostly... I did it in fixed-form and found out the !GCC$ has to start in the first column unless using free-form). I tried to extend this to arrays as follows:</p><div class="codebox"><pre><code>      subroutine aArrPbArr(a,b,c,n)
       use iso_c_binding, only: c_double, c_int
       IMPLICIT NONE
!GCC$ attributes dllexport, stdcall :: aArrPbArr
       INTEGER(kind=c_int), INTENT(IN) :: n
       REAL(kind=c_double), INTENT(IN) :: a(1:n),b(1:n)
       REAL(kind=c_double), INTENT(OUT) :: c(1:n)
       INTEGER(kind=c_int) :: i
       DO i = 1, n
        c(i) = a(i) + b(i)
       END DO
       return
      end subroutine aArrPbArr</code></pre></div><p>Excel links to it and appears to run the link to aArrPbArr, but running it does not actually keep any of the values in the c array. The c() array contains all zeros before and after running aArrPbArr. Excel VBA code is:</p><div class="codebox"><pre><code>Option Explicit

Declare Sub aArrPbArr Lib &quot;C:\[path]\Test\test.dll&quot; Alias &quot;aarrpbarr@16&quot; (ByRef a() As Double, ByRef b() As Double, ByRef c() As Double, ByRef n As Integer)

Public Sub test2()
    Const n As Integer = 5
    Dim i As Integer
    Dim a(1 To n) As Double, b(1 To n) As Double, c(1 To n) As Double
    Dim WorkString As String


    &#039;ReDim a(1 To n), b(1 To n), c(1 To n)
    a(1) = 0: a(2) = 1: a(3) = 1.5: a(4) = 1.75: a(n) = 2
    b(1) = 0: b(2) = 0.25: b(3) = 0.5: b(4) = 0.75: b(n) = 1

    Call aArrPbArr(a, b, c, n)
    WorkString = &quot;&quot;
    For i = 1 To n
        WorkString = WorkString &amp; &quot;c(&quot; &amp; CStr(i) &amp; &quot;)=&quot; &amp; CStr(c(i)) &amp; vbNewLine
    Next i
    MsgBox &quot;aArrPbArr &quot; &amp; WorkString
End Sub</code></pre></div><p>(Oh, and the commented ReDim in the VBA code was me trying to see if it would work either with fixed size or redimensionable arrays. It didn&#039;t matter.)</p><p>What am I doing wrong?</p><p>Thanks, <br />Jason</p>]]></description>
			<author><![CDATA[null@example.com (jason_b1975)]]></author>
			<pubDate>Wed, 09 Mar 2016 00:56:34 +0000</pubDate>
			<guid>https://forums.approximatrix.com/viewtopic.php?pid=2417#p2417</guid>
		</item>
		<item>
			<title><![CDATA[Re: Fortran DLL for use in Excel VBA - another round of questions]]></title>
			<link>https://forums.approximatrix.com/viewtopic.php?pid=1489#p1489</link>
			<description><![CDATA[<p>CR,</p><p>That&#039;s great to hear that it&#039;s working!</p><p>I know the process is not particularly straightforward, but that is often the nature of mixed-language programming.</p>]]></description>
			<author><![CDATA[null@example.com (jeff)]]></author>
			<pubDate>Wed, 03 Sep 2014 15:03:57 +0000</pubDate>
			<guid>https://forums.approximatrix.com/viewtopic.php?pid=1489#p1489</guid>
		</item>
		<item>
			<title><![CDATA[Re: Fortran DLL for use in Excel VBA - another round of questions]]></title>
			<link>https://forums.approximatrix.com/viewtopic.php?pid=1488#p1488</link>
			<description><![CDATA[<p>Hi Jeff:<br />Thank you for looking at this for me.&nbsp; I was not making progress.<br />I am using Windows 7 64 bit OS.<br />But my Excel is 32 bit.</p><p>So, I switched to making a 32 bit dll and it works in my Excel just fine.</p><p>Thanks!</p><p>CR</p>]]></description>
			<author><![CDATA[null@example.com (cboardman)]]></author>
			<pubDate>Wed, 03 Sep 2014 14:48:13 +0000</pubDate>
			<guid>https://forums.approximatrix.com/viewtopic.php?pid=1488#p1488</guid>
		</item>
		<item>
			<title><![CDATA[Re: Fortran DLL for use in Excel VBA - another round of questions]]></title>
			<link>https://forums.approximatrix.com/viewtopic.php?pid=1487#p1487</link>
			<description><![CDATA[<p>CR,</p><p>I&#039;ve noticed a few possible problems right off the bat.&nbsp; First, I&#039;ve noticed that you&#039;re building a 64-bit DLL.&nbsp; Is your version of Excel 64-bit?&nbsp; Microsoft provides <a href="http://office.microsoft.com/en-us/support/am-i-running-32-bit-or-64-bit-office-HA010361023.aspx">directions on how to determine which version of Excel you&#039;re using</a>.&nbsp; Excel and your DLL <strong>must</strong> be using the same setting (either 32-&nbsp; or 64-bit).&nbsp; You may see the error you&#039;re experiencing as a result of this.</p><p>Second, my directions focus on 32-bit Excel and Fortran DLLs.&nbsp; The decorations of the function declaration will change if you&#039;re using 64-bit Fortran and Excel.&nbsp; &nbsp;Specifically, there will no longer be a &quot;@12&quot; decoration (or whatever might be appropriate) after your function&#039;s name.&nbsp; That standard only applies to 32-bit DLLs utilizing the <a href="http://en.wikipedia.org/wiki/X86_calling_conventions#stdcall">stdcall calling convention</a>.&nbsp; Microsoft cleared things up considerably with 64-bit Windows, eliminating the need for the decoration.</p><p>Let me know what happens if you are, in fact, using consistent &quot;bit-ness&quot; across both Excel and your Fortran DLL.&nbsp; I suspect that may be the source of your issue.</p>]]></description>
			<author><![CDATA[null@example.com (jeff)]]></author>
			<pubDate>Wed, 03 Sep 2014 00:09:39 +0000</pubDate>
			<guid>https://forums.approximatrix.com/viewtopic.php?pid=1487#p1487</guid>
		</item>
		<item>
			<title><![CDATA[Fortran DLL for use in Excel VBA - another round of questions]]></title>
			<link>https://forums.approximatrix.com/viewtopic.php?pid=1486#p1486</link>
			<description><![CDATA[<p>Hi:<br />I am trying to use SimplyFortran to create a dll that is useable in Excel VBA, and perhaps also VB.NET in Visual Studio.</p><p>I looked at the discussion on 2013-11-11 and following days by rexxitall and Jeff&#039;s helpful comments.<br />When I copy and try to run Jeff&#039;s final types.dll example Excel will give me Run-time error &#039;48&#039;:<br />File not found: c&quot;\my-fortran\types.dll</p><p>And I get the same thing when I try my simpler example.</p><p>I don&#039;t seem to be able to register the dll, so I don&#039;t understand what is going wrong. <br />I assume I am missing something required to make a useable dll.</p><p>I am using the most recent version of SimplyFortran 2.15</p><p>My simple example is supposed to be a subroutine that takes two numbers and returns the addition, passing data types of double by reference.&nbsp; This dll works fine when called by Fortran programs, but not when using in Microsoft stuff like Excel VBA or Visual Studio VB.NET</p><p>The Fortran code is in a file called aplusb_sub.f90<br />Here is a paste of the code:</p><p>Subroutine apb(a,b,c)<br />use iso_c_binding, only: c_double<br />IMPLICIT NONE<br />!GCC$ attributes dllexport, stdcall :: apb<br />REAL(kind=c_double),INTENT(IN) :: a,b<br />REAL(kind=c_double),INTENT(OUT) :: c</p><p>c = a + b</p><p>END Subroutine<br />-----------------------------------------------------------------------------------------</p><br /><p>Here is the makefile that is used to create the dll:</p><p># Automagically generated by Approximatrix Simply Fortran 2.15<br />#<br />FC=&quot;C:\Program Files (x86)\Simply Fortran 2\mingw-w64\bin\gfortran.exe&quot;<br />CC=&quot;C:\Program Files (x86)\Simply Fortran 2\mingw-w64\bin\gcc.exe&quot;<br />AR=&quot;C:\Program Files (x86)\Simply Fortran 2\mingw-w64\bin\ar.exe&quot;<br />WRC=&quot;C:\PROGRA~2\SIMPLY~1\MINGW-~1\bin\windres.exe&quot;<br />RM=rm -f</p><p>IDIR=<br /># -I error: Directory C:\Users\cboardman\AppData\Local\\\sfpm\64\include does not exist</p><p>LDIR=<br /># -L error: Directory C:\Users\cboardman\AppData\Local\\\sfpm\64\lib does not exist</p><br /><p>OPTFLAGS= -g</p><p>SPECIALFLAGS=$(IDIR)</p><p>RCFLAGS=-O coff</p><p>PRJ_FFLAGS=-fno-underscoring -fcheck=all</p><p>PRJ_CFLAGS=</p><p>PRJ_LFLAGS=-mrtd -static</p><p>FFLAGS=$(SPECIALFLAGS) $(OPTFLAGS) $(PRJ_FFLAGS) -Jmodules </p><p>CFLAGS=$(SPECIALFLAGS) $(OPTFLAGS) $(PRJ_CFLAGS)</p><p>&quot;build\aplusb_sub.o&quot;: &quot;.\aplusb_sub.f90&quot;<br />&nbsp; &nbsp; $(FC) -c -o &quot;build\aplusb_sub.o&quot; $(FFLAGS) &quot;.\aplusb_sub.f90&quot;</p><p>clean: .SYMBOLIC<br />&nbsp; &nbsp; $(RM) &quot;build\aplusb_sub.o&quot;<br />&nbsp; &nbsp; $(RM) &quot;apb.dll&quot;</p><p>&quot;apb.dll&quot;:&nbsp; &quot;build\aplusb_sub.o&quot;<br />&nbsp; &nbsp; $(FC) -o &quot;apb.dll&quot; -shared -Wl,--out-implib=&quot;apb.dll.a&quot; -static &quot;build\aplusb_sub.o&quot; $(LDIR) $(PRJ_LFLAGS)</p><p>all: &quot;apb.dll&quot; .SYMBOLIC</p><p>-------------------------------------------------------------------------------------------</p><p>The build works and creates the apb.dll in my folder c:\my-fortran<br />Note that this folder is also in my PATH variable, and it is my primary location for my fortran programs.</p><br /><p>And I can use this dll in a hello world type program:<br />program hello<br />use iso_c_binding, only: c_double<br /> real(kind=c_double) :: a,b,c <br /> real(kind=c_double) :: ansy<br />&nbsp; print *,&quot;Hello World!&quot;<br />&nbsp; a=3.3<br />&nbsp; b=8.1<br />&nbsp; <br />&nbsp; Call apb(a,b,ansy)<br />&nbsp; &nbsp; <br />&nbsp; &nbsp;print *, &quot;from sub=&quot;, ansy<br />&nbsp; &nbsp;write(*,*)&quot;Press Enter to Continue&quot;<br />&nbsp; &nbsp;read(*,*)<br />end program hello</p><p>----------------------------------------------------------------------------------------------------------------<br />Now for the details on the Excel VBA. I have a module created to work with a macro-enabled spreadsheet (using Excel 2010).&nbsp; <br />I have the following Declare that tries to reference the dll</p><p>Declare Sub apb Lib &quot;C:\my-fortran\apb.dll&quot; Alias &quot;apb@12&quot; (ByRef a As Double, ByRef b As Double, ByRef c As Double)</p><p>I have tried this with and without the path to the dll.&nbsp; Both give me the error about not being able to find the dll</p><p>To exercise the dll I have created a public subroutine called Tryit, and I can run that from the Macros button.&nbsp; If you use it directly in a function you get the unhelpful error #Value! in the cell which references a function that calls the dll.</p><p>Here is the Tryit subroutine:<br />Public Sub Tryit()<br />&nbsp; Dim a, b, c As Double<br />&nbsp; <br />&nbsp; &nbsp;a = 2.1<br />&nbsp; &nbsp;b = 3.2<br />&nbsp; <br />&nbsp; &nbsp;Call VBdll.Addit(a, b, c)<br />MsgBox &quot;addit &quot; &amp; c</p><p>&#039;Call VBdll.Addit2(a, b, c)<br />Call apb(a, b, c)<br />MsgBox &quot;apb &quot; &amp; c<br />End Sub</p><p>-----<br />In the first Addit function call I used a dll created by VB.NET and that works.&nbsp; It is a COM enabled dll created by Visual Studio.</p><p>But on the call to apb which is supposed to reference the Fortran dll, I get the Run-time error &#039;48&#039;:<br />File not found c:\my-fortran\apb.dll</p><p>So, what do I need to do be enable that dll to work in Excel VBA?&nbsp; Or to fix it in some other way to make it useful.<br />The idea was to be able to create a much more complex subroutine in Fortran that takes multiple inputs and returns multiple outputs.</p><p>Thanks for any insight.</p><p>Regards</p><p>CR</p>]]></description>
			<author><![CDATA[null@example.com (cboardman)]]></author>
			<pubDate>Tue, 02 Sep 2014 23:56:37 +0000</pubDate>
			<guid>https://forums.approximatrix.com/viewtopic.php?pid=1486#p1486</guid>
		</item>
	</channel>
</rss>
