<?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 I have a walk-through of in Intel® Fortran Compiler</title>
    <link>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141186#M137258</link>
    <description>&lt;P&gt;I have a walk-through of communications between Fortran and C# via C++, including the VS project, which can be found on this webpage: &lt;A href="http://www.simdynamics.org/download.htm" target="_blank"&gt;http://www.simdynamics.org/download.htm&lt;/A&gt;&lt;/P&gt;

&lt;P&gt;&lt;SPAN style="font-size: 1em;"&gt;Hope it helps!&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;</description>
    <pubDate>Wed, 05 Jul 2017 17:42:48 GMT</pubDate>
    <dc:creator>Justin_v_</dc:creator>
    <dc:date>2017-07-05T17:42:48Z</dc:date>
    <item>
      <title>How to call a C function in a DLL</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141178#M137250</link>
      <description>&lt;PRE class="brush:fortran;"&gt;I have DLL from someone else that is compiled from C.  I'm trying to call a function that takes a single string argument and returns an integer value.

My test program below builds and runs, but generates an "access violation" when it calls the function in the C DLL.  Is there something simple I am missing?  I tried putting a C on the string argument i.e. 'XLTRC2.dat'C but that didn't help.
program Test
&amp;nbsp;&amp;nbsp;&amp;nbsp; implicit none
&amp;nbsp;&amp;nbsp;&amp;nbsp; interface
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Integer Function TA_PDetsFromPath(fname)
&amp;nbsp;&amp;nbsp;&amp;nbsp;character(*) fname
&amp;nbsp;&amp;nbsp;&amp;nbsp;!DEC$ ATTRIBUTES C, ALIAS:'_TA_PDetsFromPath' :: TA_PDetsFromPath
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; END Function TA_PDetsFromPath
&amp;nbsp;&amp;nbsp;&amp;nbsp; END interface

&amp;nbsp;integer i
&amp;nbsp;i = TA_PDetsFromPath('XLTRC2.dat')
end program Test
&lt;/PRE&gt;

&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 05 Jul 2017 03:57:48 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141178#M137250</guid>
      <dc:creator>Brian_Murphy</dc:creator>
      <dc:date>2017-07-05T03:57:48Z</dc:date>
    </item>
    <item>
      <title>Not having details of the</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141179#M137251</link>
      <description>&lt;P&gt;Not having details of the prototype for the C function limits our ability to answer, but my first guess would be that the character variable you pass to the C function needs to be NULL terminated, i.e. change your function call to TA_PDetsFromPath('XLTRC2.dat'//char(0)).&lt;/P&gt;

&lt;P&gt;Aside: you may want to look at the interoperability with C features of Fortran for a more portable way of calling C functions.&lt;/P&gt;

&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 05 Jul 2017 09:49:56 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141179#M137251</guid>
      <dc:creator>Mark_Lewy</dc:creator>
      <dc:date>2017-07-05T09:49:56Z</dc:date>
    </item>
    <item>
      <title>C uses null-terminated</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141180#M137252</link>
      <description>&lt;P&gt;C uses null-terminated strings; Fortran character variables have a length attribute, and that attribute has to be made available in some way -- the declaration of the variable or a '*' to signify "assumed length". The C routine in your DLL expects the terminating null, so it probably keeps consuming bytes beyond the logical end of the string until the access violation occurs.&lt;/P&gt;

&lt;P&gt;Please read the mixed language chapter of the IFort user guide. ISO C-Interoperability provides portable ways to solve your problem. If you wish to keep using the DEC$ way, add a null, i.e., char(0), to the end of the Fortran character array.&lt;/P&gt;</description>
      <pubDate>Wed, 05 Jul 2017 09:51:20 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141180#M137252</guid>
      <dc:creator>mecej4</dc:creator>
      <dc:date>2017-07-05T09:51:20Z</dc:date>
    </item>
    <item>
      <title>Thanks for the replies.</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141181#M137253</link>
      <description>&lt;P&gt;Thanks for the replies.&lt;/P&gt;

&lt;P&gt;I&amp;nbsp;changed 'XLTRC2.dat' to 'XLTRC2.dat'//char(0).&amp;nbsp; But that seemed to have no effect.&amp;nbsp; The code still builds, but crashes at the same place with the same error.&amp;nbsp; My biggest problem is I don't know what I'm doing.&lt;/P&gt;

&lt;P&gt;I have the c header file for the DLL, and it is attached.&amp;nbsp; What I think are the&amp;nbsp;most&amp;nbsp;relevant lines in this file are:&lt;/P&gt;

&lt;PRE class="brush:fortran;"&gt;line 39: #define TURBOACTIVATE_API extern "C" __declspec(dllimport)
line 53:&amp;nbsp; #define TA_CC __cdecl
line 669: TURBOACTIVATE_API HRESULT TA_CC TA_PDetsFromPath(STRCTYPE filename);

I can't figure out where HRESULT is defined, but the visual studio editor popup thing says "typedef long HRESULT'.&lt;/PRE&gt;

&lt;P&gt;I don't know what most of the above means.&amp;nbsp; Can you tell me where to look in the Intel Fortran documentation&amp;nbsp;for how to figure this out?&amp;nbsp; I think I need to get the Interface definition correct, and then the calling statement correct, and then it will work.&lt;/P&gt;

&lt;P&gt;Assuming I'm able to get this call to work, I then need to figure out how to call several other routines in the DLL,&amp;nbsp;including one&amp;nbsp;that needs a data structure passed to it (TA_IsGenuineEX line 483 in the .h file).&lt;/P&gt;</description>
      <pubDate>Wed, 05 Jul 2017 15:41:35 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141181#M137253</guid>
      <dc:creator>Brian_Murphy</dc:creator>
      <dc:date>2017-07-05T15:41:35Z</dc:date>
    </item>
    <item>
      <title>I think the problem here is</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141182#M137254</link>
      <description>&lt;P&gt;I think the problem here is that STRCTYPE is typedefed to LPCWSTR, a wide character string (2-bytes per element), not a LPCSTR (1-byte per element).&lt;/P&gt;

&lt;P&gt;You need to convert your Fortran character variable to an array of integer(c_short) elements; the last element must contain 0 to be the NULL terminator.&lt;/P&gt;

&lt;P&gt;The interface should look something like&lt;/P&gt;

&lt;PRE class="brush:fortran;"&gt;interface
    function TA_PDetsFromPath(filename) result(retval) bind("C", name="TA_PDetsFromPath")
        use, intrinsic :: iso_c_binding
        integer(c_short), dimension(*) :: filename ! LPCWSTR
        integer(c_long) :: retval ! HRESULT
    end function
end interface&lt;/PRE&gt;

&lt;P&gt;using Interoperability with C&lt;/P&gt;</description>
      <pubDate>Wed, 05 Jul 2017 16:30:27 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141182#M137254</guid>
      <dc:creator>Mark_Lewy</dc:creator>
      <dc:date>2017-07-05T16:30:27Z</dc:date>
    </item>
    <item>
      <title>Thanks for the reply.  I</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141183#M137255</link>
      <description>&lt;P&gt;Thanks for the reply.&amp;nbsp; I replaced my Interface with yours, and get the following compile error:&lt;/P&gt;

&lt;P&gt;Error&amp;nbsp;1&amp;nbsp; error #5082: Syntax error, found CHARACTER_CONSTANT 'C' when expecting one of: &amp;lt;IDENTIFIER&amp;gt;&amp;nbsp;C:\Users\Brian\Documents\Visual Studio 2010\Projects\LimeTest\LimeTest.f90&amp;nbsp;20&amp;nbsp;&lt;/P&gt;

&lt;P&gt;The Fortran-calls-C example project contains a line like &lt;FONT color="#0000ff" face="Consolas" size="2"&gt;&lt;FONT color="#0000ff" face="Consolas" size="2"&gt;&lt;FONT color="#0000ff" face="Consolas" size="2"&gt;SUBROUTINE&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt; c_routine (int_arg, str_in, str_out, str_out_len) &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color="#0000ff" face="Consolas" size="2"&gt;&lt;FONT color="#0000ff" face="Consolas" size="2"&gt;&lt;FONT color="#0000ff" face="Consolas" size="2"&gt;BIND&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;(C)&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;So I replace "C" with C but got a different error; &lt;/FONT&gt;&lt;/FONT&gt;Error&amp;nbsp;1&amp;nbsp; error #6633: The type of the actual argument differs from the type of the dummy argument.&amp;nbsp;C:\Users\Brian\Documents\Visual Studio 2010\Projects\LimeTest\LimeTest.f90&amp;nbsp;35&lt;/P&gt;

&lt;P&gt;Do I need to change some other setting in&amp;nbsp;Visual Studio?&lt;/P&gt;</description>
      <pubDate>Wed, 05 Jul 2017 16:52:07 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141183#M137255</guid>
      <dc:creator>Brian_Murphy</dc:creator>
      <dc:date>2017-07-05T16:52:07Z</dc:date>
    </item>
    <item>
      <title>Once the compile error is</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141184#M137256</link>
      <description>&lt;P&gt;Once&amp;nbsp;the compile error is solved, I expect to get another in the calling statement because a string is being passed to an integer argument.&amp;nbsp; What do I do about that?&lt;/P&gt;</description>
      <pubDate>Wed, 05 Jul 2017 16:59:47 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141184#M137256</guid>
      <dc:creator>Brian_Murphy</dc:creator>
      <dc:date>2017-07-05T16:59:47Z</dc:date>
    </item>
    <item>
      <title>I tried the following, and</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141185#M137257</link>
      <description>&lt;P&gt;I tried the following, and this will build and run without crashing. However, the return value indicates the function if failing, probably because the filename string variable is no good.&amp;nbsp; I'm passing it 'XLTRC2.dat'//char(0).&amp;nbsp; I tried &lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;C_NULL_CHAR &lt;/FONT&gt;&lt;/FONT&gt;in place of char(0) but the compiler didn't allow that.&lt;/P&gt;

&lt;PRE class="brush:fortran;"&gt;interface
&amp;nbsp;&amp;nbsp;&amp;nbsp; function TA_PDetsFromPath(filename) result(retval) bind(C, name="TA_PDetsFromPath")
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; use, intrinsic :: iso_c_binding
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CHARACTER(KIND=C_CHAR), DIMENSION(*), INTENT(IN) ::&amp;nbsp;&amp;nbsp; filename 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; integer(c_long) :: retval ! HRESULT
&amp;nbsp;&amp;nbsp;&amp;nbsp; end function
end interface
&lt;/PRE&gt;

&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 05 Jul 2017 17:24:58 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141185#M137257</guid>
      <dc:creator>Brian_Murphy</dc:creator>
      <dc:date>2017-07-05T17:24:58Z</dc:date>
    </item>
    <item>
      <title>I have a walk-through of</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141186#M137258</link>
      <description>&lt;P&gt;I have a walk-through of communications between Fortran and C# via C++, including the VS project, which can be found on this webpage: &lt;A href="http://www.simdynamics.org/download.htm" target="_blank"&gt;http://www.simdynamics.org/download.htm&lt;/A&gt;&lt;/P&gt;

&lt;P&gt;&lt;SPAN style="font-size: 1em;"&gt;Hope it helps!&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;</description>
      <pubDate>Wed, 05 Jul 2017 17:42:48 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141186#M137258</guid>
      <dc:creator>Justin_v_</dc:creator>
      <dc:date>2017-07-05T17:42:48Z</dc:date>
    </item>
    <item>
      <title>Passing strings between</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141187#M137259</link>
      <description>&lt;P&gt;Passing strings between Fortran and alternative versions of C can be a real pain - a solid work-around that I have found, is to conver the string to an integer vector, and decode after the vector is passed.&lt;/P&gt;</description>
      <pubDate>Wed, 05 Jul 2017 18:42:02 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141187#M137259</guid>
      <dc:creator>Justin_v_</dc:creator>
      <dc:date>2017-07-05T18:42:02Z</dc:date>
    </item>
    <item>
      <title>Go back to the interface of</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141188#M137260</link>
      <description>&lt;P&gt;Go back to the interface of Quote #5, but try an actual argument of&lt;/P&gt;

&lt;P&gt;IACHAR(transfer('XLTRC2.dat'//C_NULL_CHAR,[C_NULL_CHAR]),KIND=C_SHORT)&lt;/P&gt;

&lt;P&gt;That would have the right TKR to make the compiler happy. Make sure that the caller also USEs ISO_C_BINDING.&lt;/P&gt;

&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 05 Jul 2017 19:36:40 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141188#M137260</guid>
      <dc:creator>JVanB</dc:creator>
      <dc:date>2017-07-05T19:36:40Z</dc:date>
    </item>
    <item>
      <title>That worked!  Thanks bunches,</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141189#M137261</link>
      <description>&lt;P&gt;That worked!&amp;nbsp; Thanks bunches, RO.&amp;nbsp; I now have my first two calls working, each of which&amp;nbsp;takes a single string input argument.&amp;nbsp; The next call has&amp;nbsp;a string argument for &lt;U&gt;output&lt;/U&gt;.&amp;nbsp; Can you tell me how to pass that sort of argument?&amp;nbsp; I've taken a stab at it, but no luck.&lt;/P&gt;</description>
      <pubDate>Wed, 05 Jul 2017 20:52:59 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141189#M137261</guid>
      <dc:creator>Brian_Murphy</dc:creator>
      <dc:date>2017-07-05T20:52:59Z</dc:date>
    </item>
    <item>
      <title>There is a bit of ambiguity</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141190#M137262</link>
      <description>&lt;P&gt;There is a bit of ambiguity in Quote #12 in that the C++ function could take an array of wchar_t, supposed allocated big enough, as an argument and then just fill it with data (type1) or it could take a pointer to a pointer to wchar_t and point the middle pointer at a wchar_t string that the library manages (type2). Accordingly I have given an example for both possibilities. Note that it uses wcslen() from MSVCRT and for older versions of ifort it needs the command line switch /assume:realloc_lhs. I compiled the C part with gcc:&lt;/P&gt;

&lt;PRE class="brush:cpp;"&gt;#include &amp;lt;windows.h&amp;gt;

wchar_t hello[] = {(wchar_t)'H',(wchar_t)'e',(wchar_t)'l',
&amp;nbsp;&amp;nbsp; (wchar_t)'l',(wchar_t)'o',(wchar_t)',',(wchar_t)' ',
&amp;nbsp;&amp;nbsp; (wchar_t)'w',(wchar_t)'o',(wchar_t)'r',(wchar_t)'l',
&amp;nbsp;&amp;nbsp; (wchar_t)'d',(wchar_t)'\0'};

void type1(wchar_t *str)
{
&amp;nbsp;&amp;nbsp; int i;
&amp;nbsp;&amp;nbsp; for(i = 0; hello&lt;I&gt; != (wchar_t)'\0'; i++)
&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; str&lt;I&gt; = hello&lt;I&gt;;
&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp; str&lt;I&gt; = hello&lt;I&gt;;
}

void type2(wchar_t **str)
{
&amp;nbsp;&amp;nbsp; *str = hello;
}
&lt;/I&gt;&lt;/I&gt;&lt;/I&gt;&lt;/I&gt;&lt;/I&gt;&lt;/PRE&gt;

&lt;P&gt;And I compiled the fortran part with ifort (which also linked with the *.o file that gcc made):&lt;/P&gt;

&lt;PRE class="brush:fortran;"&gt;module M
&amp;nbsp;&amp;nbsp; use ISO_C_BINDING
&amp;nbsp;&amp;nbsp; implicit none
&amp;nbsp;&amp;nbsp; private
&amp;nbsp;&amp;nbsp; public type1, type2, wcslen
&amp;nbsp;&amp;nbsp; interface
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; subroutine type1(str) bind(C,name='type1')
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; import
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; implicit none
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; integer(C_SHORT) str(*)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end subroutine type1

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; subroutine type2(str) bind(C,name='type2')
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; import
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; implicit none
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; type(C_PTR) str
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end subroutine type2
&amp;nbsp;&amp;nbsp; end interface

&amp;nbsp;&amp;nbsp; interface wcslen
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; function wcslen_array(str) bind(C,name='wcslen')
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; import
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; implicit none
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; integer(C_SIZE_T) wcslen_array
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; integer(C_SHORT) str(*)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end function wcslen_array

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; function wcslen_pointer(str) bind(C,name='wcslen')
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; import
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; implicit none
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; integer(C_SIZE_T) wcslen_pointer
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; type(C_PTR), value :: str
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end function wcslen_pointer
&amp;nbsp;&amp;nbsp; end interface wcslen
end module M

program P
&amp;nbsp;&amp;nbsp; use M
&amp;nbsp;&amp;nbsp; use ISO_C_BINDING
&amp;nbsp;&amp;nbsp; implicit none
&amp;nbsp;&amp;nbsp; integer(C_SHORT), allocatable :: str1(:)
&amp;nbsp;&amp;nbsp; character(len=:,kind=C_CHAR), allocatable :: result1
&amp;nbsp;&amp;nbsp; integer(C_SIZE_T) strlen1
&amp;nbsp;&amp;nbsp; type(C_PTR) str2
&amp;nbsp;&amp;nbsp; integer(C_SIZE_T) strlen2
&amp;nbsp;&amp;nbsp; integer(C_SHORT), pointer :: array2(:)
&amp;nbsp;&amp;nbsp; character(len=:,kind=C_CHAR), allocatable :: result2

&amp;nbsp;&amp;nbsp; allocate(str1(20)) ! Or however big it has to be to hold result
&amp;nbsp;&amp;nbsp; call type1(str1)
&amp;nbsp;&amp;nbsp; strlen1 = wcslen(str1)
&amp;nbsp;&amp;nbsp; result1 = transfer(achar(str1),repeat('A',strlen1))
&amp;nbsp;&amp;nbsp; write(*,'(*(g0))') 'Result for type1 = ',result1

&amp;nbsp;&amp;nbsp; call type2(str2)
&amp;nbsp;&amp;nbsp; strlen2 = wcslen(str2)
&amp;nbsp;&amp;nbsp; call C_F_POINTER(str2, array2, [strlen2])
&amp;nbsp;&amp;nbsp; result2 = transfer(achar(array2), repeat('A',strlen2))
&amp;nbsp;&amp;nbsp; write(*,'(*(g0))') 'Result for type2 = ',result2
end program P
&lt;/PRE&gt;

&lt;P&gt;Also the above worked with gfortran. Results were the same with both fortran processors:&lt;/P&gt;

&lt;PRE class="brush:plain;"&gt;Result for type1 = Hello, world
Result for type2 = Hello, world&lt;/PRE&gt;

&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 05 Jul 2017 22:42:59 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141190#M137262</guid>
      <dc:creator>JVanB</dc:creator>
      <dc:date>2017-07-05T22:42:59Z</dc:date>
    </item>
    <item>
      <title>Thanks for the reply, RO. </title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141191#M137263</link>
      <description>&lt;P&gt;Thanks for the reply, RO.&amp;nbsp; However, I have to confess this is getting to be too far over my head.&amp;nbsp; My original goal was to simplify things by eliminating the use of C code to call the routines in the DLL.&amp;nbsp;&amp;nbsp;C code which calls the DLL's routines&amp;nbsp;is pretty simple, and I have that working.&amp;nbsp; That was easy to get working because I only really need to return a single integer value from C to fortran.&amp;nbsp; So all the tricky calling of&amp;nbsp;DLL routines is done in C.&lt;/P&gt;

&lt;P&gt;It would have been nice to eliminate the C code and do it all in fortran if the fortran code isn't too complicated.&amp;nbsp; But the way this is going, the fortran code will be too complicated for me to understand,&amp;nbsp;or for the next guy after me to understand.&amp;nbsp;&amp;nbsp;Thus&amp;nbsp;sticking with using C to call the DLL seems like my best choice.&lt;/P&gt;

&lt;P&gt;I really appreciate the help.&amp;nbsp; I've learned some new things, and I don't want to appear ungrateful.&lt;/P&gt;</description>
      <pubDate>Wed, 05 Jul 2017 23:55:26 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141191#M137263</guid>
      <dc:creator>Brian_Murphy</dc:creator>
      <dc:date>2017-07-05T23:55:26Z</dc:date>
    </item>
    <item>
      <title>I didn't think that two or</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141192#M137264</link>
      <description>&lt;P&gt;I didn't think that two or three executable statements to convert the actual argument to something Fortran-usable was all that complicated. TT&lt;/P&gt;

&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 06 Jul 2017 01:57:07 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141192#M137264</guid>
      <dc:creator>JVanB</dc:creator>
      <dc:date>2017-07-06T01:57:07Z</dc:date>
    </item>
    <item>
      <title>I wish it were at simple to</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141193#M137265</link>
      <description>&lt;P&gt;I wish it were at simple to me as it is to you.&amp;nbsp; Converting "a few lines of code" is mushrooming into&amp;nbsp;loads of code.&amp;nbsp; I did try one of the methods you described, and I get an&amp;nbsp;access violation&amp;nbsp;in the call to wcslen, and the debugger says a bad pointer&amp;nbsp;was passed to wcslen.&lt;/P&gt;</description>
      <pubDate>Thu, 06 Jul 2017 03:04:05 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141193#M137265</guid>
      <dc:creator>Brian_Murphy</dc:creator>
      <dc:date>2017-07-06T03:04:05Z</dc:date>
    </item>
    <item>
      <title>I was hoping you could figure</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141194#M137266</link>
      <description>&lt;P&gt;I was hoping you could figure out whether type1 or type2 was applicable from reading the documentation, if available, or the C code. But documentation can be sparse and C is an incomprehensible language when coming from a Fortran background. Can you give the C prototype as you did in Quote #4? Your symptoms make it look like you are assuming type2 when the *.DLL really wants type1, or that it's type2 with the string not NUL-terminated, but its length passed in another argument or the function result.&lt;/P&gt;

&lt;P&gt;If you just can't make it work, can you give a small compilable example that shows the error (just the Fortran part, hopefully you are going to disclose the C prototype anyway).&lt;/P&gt;

&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 06 Jul 2017 03:50:53 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141194#M137266</guid>
      <dc:creator>JVanB</dc:creator>
      <dc:date>2017-07-06T03:50:53Z</dc:date>
    </item>
    <item>
      <title>type2 was the one I tried.</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141195#M137267</link>
      <description>&lt;P&gt;type2 was the one I tried.&lt;/P&gt;

&lt;P&gt;I don't have any documentation on the routines in the DLL other than the header file attached to post #4.&amp;nbsp; I have to go to bed now, but the prototype is line 387 in the header file.&amp;nbsp; Here is&amp;nbsp;line 387.&lt;/P&gt;

&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;TURBOACTIVATE_API HRESULT TA_CC TA_GetFeatureValue(uint32_t handle, STRCTYPE featureName, STRTYPE lpValueStr, &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color="#0000ff" face="Consolas" size="2"&gt;&lt;FONT color="#0000ff" face="Consolas" size="2"&gt;&lt;FONT color="#0000ff" face="Consolas" size="2"&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt; cchValue);&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;The comments in the header file say this routine is called twice, and that is what I am doing.&amp;nbsp; In the first call&amp;nbsp;it returns the size of the string that is going to be returned in the second call.&amp;nbsp; The first call seems to go ok since cchValue returns a number that looks about right.&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;Assuming I get past this routine, the next one&amp;nbsp;is the last one I need to call, but one of its arguments&amp;nbsp;is a typedef data structure consisting of 4 long variables (thankfully no strings).&amp;nbsp; Prototype for this one is line 483 in the header file, and it takes a pointer to a data structure variable.&amp;nbsp; Yikes!&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;</description>
      <pubDate>Thu, 06 Jul 2017 04:06:47 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141195#M137267</guid>
      <dc:creator>Brian_Murphy</dc:creator>
      <dc:date>2017-07-06T04:06:47Z</dc:date>
    </item>
    <item>
      <title>Here are my suggested</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141196#M137268</link>
      <description>&lt;P&gt;Here are my suggested interfaces to the two functions you mention in #18:&lt;/P&gt;

&lt;PRE class="brush:fortran;"&gt;module turboactive_api_mod
    use, intrinsic :: iso_c_binding

    implicit none

    type, bind(c) :: GENUINE_OPTIONS
        ! The size, in bytes, of this structure. Set this value to the size of the GENUINE_OPTIONS structure.
        integer(c_int32_t) :: nLength;

        ! Flags to pass to TA_IsGenuineEx() to control its behavior.
        integer(c_int32_t) :: flags;

        ! How often to contact the LimeLM servers for validation. 90 days recommended.
        integer(c_int32_t) :: nDaysBetweenChecks;

        ! If the call fails because of an internet error, how long, in days, should the grace period last (before
        ! returning deactivating and returning TA_FAIL). 14 days is recommended.
        integer(c_int32_t) :: nGraceDaysOnInetErr;
    end type GENUINE_OPTIONS

    interface
        ! Add other function prototypes here...

        ! TURBOACTIVATE_API HRESULT TA_CC TA_GetFeatureValue(uint32_t handle, STRCTYPE featureName, STRTYPE lpValueStr, int cchValue);
        function TA_GetFeatureValue(handle, featureName, lpValueStr, cchValue) bind(c, name = 'TA_GetFeatureValue') result(retval)
            import
            integer(c_int32_t), value :: handle ! Note that Fortran doesn't have unsigned integer types
            integer(c_short), dimension(*) :: featureName ! LPCWSTR is a "Long Pointer to Constant Wide String". 
            integer(c_short), dimension(*) :: lpValueStr ! LPWSTR is a pointer to a string of 16-bit Unicode characters, which MAY be null-terminated. 
            integer(c_int), value :: cchValue ! Note the value attribute here
            integer(c_long) :: retval ! HRESULT is typedef long
        end function

        ! TURBOACTIVATE_API HRESULT TA_CC TA_IsGenuineEx(uint32_t handle, PGENUINE_OPTIONS options);
        function TA_IsGenuineEx(handle, options) bind(c, name = 'TA_IsGenuineEx') result(retval)
            import
            integer(c_int32_t), value :: handle ! Note that Fortran doesn't have unsigned integer types
            type(GENUINE_OPTIONS) :: options
            integer(c_long) :: retval ! HRESULT is typedef long
        end function
    end interface
end module turboactive_api_mod
    &lt;/PRE&gt;

&lt;P&gt;A few things to note:&lt;/P&gt;

&lt;P&gt;1) You normally don't need to add the value attribute to the declarations of types that are passed as pointers to C.&lt;/P&gt;

&lt;P&gt;2) On the other hand, you will need the value attribute for things passed by value, e.g. cchValue.&lt;/P&gt;

&lt;P&gt;3) You could use the ifwin module to get definitions for the Windows API types (e.g. HRESULT), but this wouldn't be portable to other compilers.&lt;/P&gt;

&lt;P&gt;4) Fortran only supports signed integers, hence the use of c_int32_t not c_uint32_t.&lt;/P&gt;

&lt;P&gt;5) Interoperable types are quite straightforward - you need to add the bind(c) attribute.&lt;/P&gt;

&lt;P&gt;6) The Standard Tools for Interoperability help topic is your friend :-)&lt;/P&gt;

&lt;P&gt;7) As you mention, you would normally call TA_GetFeatureValue() twice.&amp;nbsp; The first time with cchValue = 0 to get the function to return the buffer size.&amp;nbsp; Once you know this, you can allocate an array of integer(c_short) to the buffer size to store the value of the custom licence field and pass this and the buffer size on the 2nd call.&lt;/P&gt;</description>
      <pubDate>Thu, 06 Jul 2017 08:54:00 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141196#M137268</guid>
      <dc:creator>Mark_Lewy</dc:creator>
      <dc:date>2017-07-06T08:54:00Z</dc:date>
    </item>
    <item>
      <title>Thanks bunches for the help. </title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141197#M137269</link>
      <description>&lt;P&gt;Thanks bunches for the help.&amp;nbsp; After some more peek and poke, I've actually got it all working!&amp;nbsp; To pass a data structure variable, I am simply using the name of the variable, and that works!&amp;nbsp; Too bad strings aren't that easy.&lt;/P&gt;

&lt;P&gt;This brings to mind the&amp;nbsp;old saying "I only know enough to be dangerous".&amp;nbsp; I was already dangerous, and now even more so :)&lt;/P&gt;

&lt;P&gt;I will pass&amp;nbsp;this back to the Turboactivate people.&amp;nbsp; They said they didn't have fortran sample code for calling their API, so they ought to want this.&lt;/P&gt;</description>
      <pubDate>Thu, 06 Jul 2017 21:52:41 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/How-to-call-a-C-function-in-a-DLL/m-p/1141197#M137269</guid>
      <dc:creator>Brian_Murphy</dc:creator>
      <dc:date>2017-07-06T21:52:41Z</dc:date>
    </item>
  </channel>
</rss>

