<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Passing a subroutine as an argument in a DLL in Intel® Fortran Compiler</title>
    <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Passing-a-subroutine-as-an-argument-in-a-DLL/m-p/840247#M58216</link>
    <description>&lt;P class="MsoNormal"&gt;Hello All,&lt;BR /&gt;
&lt;BR /&gt;
I've been searching on the forum intermittently for about a month now, and
either my problem isn't represented, or I'm not looking in the right places.
Nonetheless, here it is: I have created a Visual Studio / Fortran program that
uses a Visual Studio GUI to call the Fortran DLL. Everything seems to work fine
in that regard. My problem is that, within the Fortran DLL, I am attempting to
pass a subroutine as an argument into the November 2003 version of LLNL's
DLSODA subroutine (I'm sure it doesn't matter what the destination is, but just
in case). Here's the call that occurs within the DLL:&lt;BR /&gt;
&lt;BR /&gt;
&lt;B&gt;&lt;SPAN style="color: blue;"&gt;CALL &lt;/SPAN&gt;&lt;/B&gt;dlsoda(fex_fun,neq,f,xin,xout,itol,rtol,atol, &amp;amp;&lt;/P&gt;&lt;P class="MsoNormal"&gt;itask,istate,iopt,rwork,lrw,iwork,liw,jac,jt)&lt;BR /&gt;
&lt;BR /&gt;
The subroutine is "fex_fun", and is declared elsewhere as:&lt;BR /&gt;
&lt;BR /&gt;
&lt;B&gt;&lt;SPAN style="color: blue;"&gt;SUBROUTINE &lt;/SPAN&gt;&lt;/B&gt;fex_fun(NEQ, X, F, FPRIME)&lt;BR /&gt;
&lt;BR /&gt;
How should I declare (and where) this fex_fun subroutine so that I can call it
as an argument in another subroutine? I've tried using the EXTERNAL declaration,
but I must not be using it correctly. Any help would be appreciated.&lt;/P&gt;</description>
    <pubDate>Mon, 09 Jul 2007 20:56:17 GMT</pubDate>
    <dc:creator>jdchambless</dc:creator>
    <dc:date>2007-07-09T20:56:17Z</dc:date>
    <item>
      <title>Passing a subroutine as an argument in a DLL</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Passing-a-subroutine-as-an-argument-in-a-DLL/m-p/840247#M58216</link>
      <description>&lt;P class="MsoNormal"&gt;Hello All,&lt;BR /&gt;
&lt;BR /&gt;
I've been searching on the forum intermittently for about a month now, and
either my problem isn't represented, or I'm not looking in the right places.
Nonetheless, here it is: I have created a Visual Studio / Fortran program that
uses a Visual Studio GUI to call the Fortran DLL. Everything seems to work fine
in that regard. My problem is that, within the Fortran DLL, I am attempting to
pass a subroutine as an argument into the November 2003 version of LLNL's
DLSODA subroutine (I'm sure it doesn't matter what the destination is, but just
in case). Here's the call that occurs within the DLL:&lt;BR /&gt;
&lt;BR /&gt;
&lt;B&gt;&lt;SPAN style="color: blue;"&gt;CALL &lt;/SPAN&gt;&lt;/B&gt;dlsoda(fex_fun,neq,f,xin,xout,itol,rtol,atol, &amp;amp;&lt;/P&gt;&lt;P class="MsoNormal"&gt;itask,istate,iopt,rwork,lrw,iwork,liw,jac,jt)&lt;BR /&gt;
&lt;BR /&gt;
The subroutine is "fex_fun", and is declared elsewhere as:&lt;BR /&gt;
&lt;BR /&gt;
&lt;B&gt;&lt;SPAN style="color: blue;"&gt;SUBROUTINE &lt;/SPAN&gt;&lt;/B&gt;fex_fun(NEQ, X, F, FPRIME)&lt;BR /&gt;
&lt;BR /&gt;
How should I declare (and where) this fex_fun subroutine so that I can call it
as an argument in another subroutine? I've tried using the EXTERNAL declaration,
but I must not be using it correctly. Any help would be appreciated.&lt;/P&gt;</description>
      <pubDate>Mon, 09 Jul 2007 20:56:17 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Passing-a-subroutine-as-an-argument-in-a-DLL/m-p/840247#M58216</guid>
      <dc:creator>jdchambless</dc:creator>
      <dc:date>2007-07-09T20:56:17Z</dc:date>
    </item>
    <item>
      <title>Re: Passing a subroutine as an argument in a DLL</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Passing-a-subroutine-as-an-argument-in-a-DLL/m-p/840248#M58217</link>
      <description>Is there an explicit interface for dlsoda? If so, you'll need to match how it declares the routine argument. It may have "external", in which case all you need is:&lt;BR /&gt;&lt;BR /&gt;external fex_fun&lt;BR /&gt;&lt;BR /&gt;or it may have a complete explicit interface nested within the interface for dlsoda. If that's the case, then you'll need to write a compatible explicit interface for fex_fun.&lt;BR /&gt;&lt;BR /&gt;Is this dlsoda Fortran code that you also compiled with the Intel compiler, or is it in some other library or DLL? If it isn't Fortran source, you will need to know dlsoda's calling convention.&lt;BR /&gt;&lt;BR /&gt;What error messages are you seeing?&lt;BR /&gt;</description>
      <pubDate>Tue, 10 Jul 2007 00:14:19 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Passing-a-subroutine-as-an-argument-in-a-DLL/m-p/840248#M58217</guid>
      <dc:creator>Steven_L_Intel1</dc:creator>
      <dc:date>2007-07-10T00:14:19Z</dc:date>
    </item>
    <item>
      <title>Re: Passing a subroutine as an argument in a DLL</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Passing-a-subroutine-as-an-argument-in-a-DLL/m-p/840249#M58218</link>
      <description>&lt;P class="MsoNormal" style="text-indent: 0.5in;"&gt;&lt;BR /&gt;Hi Steve. Thanks for the quick reply. The DLSODA routine is
part of the much larger ODEPACK.F file put out by LLNL. Though, I am attempting
to only use the part concerned with DLSODA, since the whole file is more than
27,000 lines long. I am compiling the DLSODA routine by including it in a
separate file and module, like this:&lt;BR /&gt;
&lt;B&gt;&lt;SPAN style="color: blue;"&gt;&lt;BR /&gt;
&lt;/SPAN&gt;&lt;/B&gt;&lt;SPAN style="color: green;"&gt;!dlsoda.f90&lt;BR /&gt;
&lt;/SPAN&gt;&lt;B&gt;&lt;SPAN style="color: blue;"&gt;MODULE&lt;/SPAN&gt;&lt;/B&gt; DLSODA_MOD&lt;BR /&gt;
 public :: dlsoda&lt;BR /&gt;
&lt;B&gt;&lt;SPAN style="color: blue;"&gt;contains&lt;BR /&gt;
 subroutine&lt;/SPAN&gt;&lt;/B&gt; dlsoda(FEX_FUN,...)&lt;B&gt;&lt;SPAN style="color: blue;"&gt;&lt;BR /&gt;   external &lt;/SPAN&gt;&lt;/B&gt;FEX_FUN  &lt;BR /&gt;   ...&lt;BR /&gt;
 &lt;B&gt;&lt;SPAN style="color: blue;"&gt;end subroutine&lt;/SPAN&gt;&lt;/B&gt; dlsoda&lt;B&gt;&lt;SPAN style="color: blue;"&gt;&lt;BR /&gt;END MODULE &lt;/SPAN&gt;&lt;/B&gt;DLSODA_MOD&lt;BR /&gt;
&lt;BR /&gt;
The FEX_FUN subroutine is placed in the same file as the subroutine that calls
DLSODA, like this:&lt;BR /&gt;
&lt;BR /&gt;
&lt;SPAN style="color: green;"&gt;!main.f90&lt;/SPAN&gt;&lt;BR /&gt;
&lt;B&gt;&lt;SPAN style="color: blue;"&gt;MODULE &lt;/SPAN&gt;&lt;/B&gt;main_mod&lt;BR /&gt;
 public :: caller_sub&lt;BR /&gt;
&lt;B&gt;&lt;SPAN style="color: blue;"&gt;contains&lt;/SPAN&gt;&lt;/B&gt;&lt;BR /&gt;
 &lt;B&gt;&lt;SPAN style="color: blue;"&gt;subroutine&lt;/SPAN&gt;&lt;/B&gt;
caller_sub(...)&lt;BR /&gt;
  &lt;B&gt;&lt;SPAN style="color: blue;"&gt;use&lt;/SPAN&gt;&lt;/B&gt;
DLSODA_MOD&lt;BR /&gt;
  ...&lt;BR /&gt;
&lt;B&gt;&lt;SPAN style="color: blue;"&gt;&lt;SPAN style=""&gt; &lt;/SPAN&gt;CALL&lt;/SPAN&gt;&lt;/B&gt;
dlsoda(FEX_FUN,...)&lt;BR /&gt;  ...&lt;BR /&gt;
 &lt;B&gt;&lt;SPAN style="color: blue;"&gt;end subroutine&lt;/SPAN&gt;&lt;/B&gt;
caller_sub&lt;BR /&gt;
&lt;SPAN style="color: green;"&gt;!!**************************!!&lt;/SPAN&gt;&lt;BR /&gt;
 &lt;B&gt;&lt;SPAN style="color: blue;"&gt;subroutine&lt;/SPAN&gt;&lt;/B&gt;
FEX_FUN(...)&lt;BR /&gt;
  ...&lt;BR /&gt;
 &lt;B&gt;&lt;SPAN style="color: blue;"&gt;end subroutine&lt;/SPAN&gt;&lt;/B&gt;
FEX_FUN&lt;BR /&gt;
&lt;BR /&gt;
&lt;B&gt;&lt;SPAN style="color: blue;"&gt;END MODULE &lt;/SPAN&gt;&lt;/B&gt;main_mod&lt;BR /&gt;
&lt;BR /&gt;
I attempted to simply put "&lt;B&gt;&lt;SPAN style="color: blue;"&gt;external &lt;/SPAN&gt;&lt;/B&gt;FEX_FUN"
in the declarations of the caller_sub subroutine, but I get this error:&lt;BR /&gt;
&lt;BR /&gt;
MAIN.obj : error LNK2019: unresolved external symbol _FEX_FUN referenced in
function _MAIN_MOD_mp_CALLER_SUB&lt;BR /&gt;
&lt;BR /&gt;
Let me know if any more information is required.&lt;/P&gt;</description>
      <pubDate>Tue, 10 Jul 2007 14:48:31 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Passing-a-subroutine-as-an-argument-in-a-DLL/m-p/840249#M58218</guid>
      <dc:creator>jdchambless</dc:creator>
      <dc:date>2007-07-10T14:48:31Z</dc:date>
    </item>
    <item>
      <title>Re: Passing a subroutine as an argument in a DLL</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Passing-a-subroutine-as-an-argument-in-a-DLL/m-p/840250#M58219</link>
      <description>Ah, ok. Take out the EXTERNAL in main.f90 - you don't need it. Using the module main_mod properly declares fex_fun. You would need EXTERNAL (or an interface block) only if you did not already have an explicit interface visible for fex_fun. Since you do, nothing else is required.&lt;BR /&gt;</description>
      <pubDate>Tue, 10 Jul 2007 15:22:22 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Passing-a-subroutine-as-an-argument-in-a-DLL/m-p/840250#M58219</guid>
      <dc:creator>Steven_L_Intel1</dc:creator>
      <dc:date>2007-07-10T15:22:22Z</dc:date>
    </item>
    <item>
      <title>Re: Passing a subroutine as an argument in a DLL</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Passing-a-subroutine-as-an-argument-in-a-DLL/m-p/840251#M58220</link>
      <description>Hi Steve. That appears to have worked great. Would you mind elaborating a little on why this worked?&lt;BR /&gt;&lt;BR /&gt;Thanks again,&lt;BR /&gt;Jason&lt;BR /&gt;</description>
      <pubDate>Tue, 10 Jul 2007 15:54:41 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Passing-a-subroutine-as-an-argument-in-a-DLL/m-p/840251#M58220</guid>
      <dc:creator>jdchambless</dc:creator>
      <dc:date>2007-07-10T15:54:41Z</dc:date>
    </item>
    <item>
      <title>Re: Passing a subroutine as an argument in a DLL</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Passing-a-subroutine-as-an-argument-in-a-DLL/m-p/840252#M58221</link>
      <description>Let's say you have:&lt;BR /&gt;&lt;BR /&gt;call foo(mysub)&lt;BR /&gt;&lt;BR /&gt;The compiler needs to figure out what "mysub" is - it could be a variable or it could be a routine. If no other information is available, it's a variable. Simple. If you give mysub a type, it could still be a variable or a function. Somehow the compiler has to know it's a routine.&lt;BR /&gt;&lt;BR /&gt;The F77 way to do this, which was the only way in F77, was to add an EXTERNAL declaration for mysub. This informs the compiler that it is an external procedure, or "confirms" that mysub is a BLOCK DATA subprogram which is part of the application. Either way, this gives the compiler enough information to generate an external reference to mysub (normally _MYSUB on IA-32) and pass that address as the argument.&lt;BR /&gt;&lt;BR /&gt;In F90, we have explicit interfaces which can be provided several ways. Any of them, if visible to the caller, will let the compiler know that mysub is a routine and not a variable. When mysub is a module procedure the compiler also knows how to decorate the external name relating to the module, for example, _MODNAME_mp_MYSUB, since you could theoretically have two or more routines named MYSUB in the application (just can't use the name if two definitions are visible at the same time.)&lt;BR /&gt;&lt;BR /&gt;So in your program, the compiler already knew that fex_fun was a function and how to find it - nothing else was needed. In fact, adding EXTERNAL hid your module procedure ext_fun and told the compiler that you wanted some other external procedure, which is what produced the reference to _EXT_FUN.&lt;BR /&gt;&lt;BR /&gt;Note that while it is standard-conforming to pass a module procedure as an actual argument, it is NOT standard to pass a contained procedure (a procedure contained inside another procedure.) The standard has a note saying how this should work if a compler should choose to support this as an extension, and indeed Intel Fortran does.&lt;BR /&gt;</description>
      <pubDate>Tue, 10 Jul 2007 16:10:45 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Passing-a-subroutine-as-an-argument-in-a-DLL/m-p/840252#M58221</guid>
      <dc:creator>Steven_L_Intel1</dc:creator>
      <dc:date>2007-07-10T16:10:45Z</dc:date>
    </item>
    <item>
      <title>Re: Passing a subroutine as an argument in a DLL</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Passing-a-subroutine-as-an-argument-in-a-DLL/m-p/840253#M58222</link>
      <description>I appreciate the explanation. I am relatively new to Fortran, so the conceptual stuff really helps. I had another one for you (or anyone in here) if you have a minute:&lt;BR /&gt;In that same setup as above, there is a variable declared in caller_sub called RTEMP. I need to use RTEMP in the FEX_FUN subroutine, but that variable isn't passed into FEX_FUN as an argument. So, conceptually, how do I give a subroutine access to a variable that has been used previously in other subroutines, without actually passing it in as an argument? I'm sure this is exceedingly easy to do, but probably so easy that I'm overlooking it (as we engineers tend to do).&lt;BR /&gt;&lt;BR /&gt;Thanks.&lt;BR /&gt;</description>
      <pubDate>Fri, 13 Jul 2007 16:14:15 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Passing-a-subroutine-as-an-argument-in-a-DLL/m-p/840253#M58222</guid>
      <dc:creator>jdchambless</dc:creator>
      <dc:date>2007-07-13T16:14:15Z</dc:date>
    </item>
    <item>
      <title>Re: Passing a subroutine as an argument in a DLL</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Passing-a-subroutine-as-an-argument-in-a-DLL/m-p/840254#M58223</link>
      <description>&lt;P&gt;I like the easy ones...&lt;/P&gt;
&lt;P&gt;Put it in a MODULE and USE the module in the routines in which you want the variable to be available.&lt;/P&gt;
&lt;P&gt;MODULE MYGLOBALS&lt;BR /&gt;INTEGER I&lt;BR /&gt;REAL*8 R&lt;BR /&gt;CHARACTER*100 FILENAME&lt;BR /&gt;END MODULE&lt;/P&gt;
&lt;P&gt;SUBROUTINE FOO(A,B,C,D, E, J,K)&lt;BR /&gt;USE MYGLOBALS&lt;BR /&gt;INTEGER J,K&lt;BR /&gt;REAL*8 A,B,C,D,E&lt;BR /&gt;R=A&lt;BR /&gt;I=J&lt;BR /&gt;RETURN&lt;BR /&gt;END SUBROUTINE FOO&lt;/P&gt;</description>
      <pubDate>Fri, 13 Jul 2007 22:45:39 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Passing-a-subroutine-as-an-argument-in-a-DLL/m-p/840254#M58223</guid>
      <dc:creator>anthonyrichards</dc:creator>
      <dc:date>2007-07-13T22:45:39Z</dc:date>
    </item>
  </channel>
</rss>

