• calling wide UTF-16 Win32 functions in a Intel Fortran Win32 DLL

    From Lynn McGuire@21:1/5 to All on Mon Jan 31 14:03:58 2022
    Does anyone know how to call wide UTF-16 Win32 functions in a Intel
    Fortran Win32 DLL ? The linker in Visual Studio cannot link in GetWindowsDirectoryW that I am calling in my C code in the Ifort Win32
    DLL. I am going to use the LoadLibrary route but I really do not want
    to do this unless I have to.

    Thanks,
    Lynn

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James Van Buskirk@21:1/5 to Lynn McGuire on Tue Feb 1 01:45:32 2022
    "Lynn McGuire" wrote in message news:st9fbe$igp$1@dont-email.me...

    Does anyone know how to call wide UTF-16 Win32 functions in a Intel
    Fortran Win32 DLL ? The linker in Visual Studio cannot link in GetWindowsDirectoryW that I am calling in my C code in the Ifort Win32
    DLL. I am going to use the LoadLibrary route but I really do not want to
    do this unless I have to.

    GetWindowsDirectoryW is in kernel32.dll so it should work with no problems. Indeed,

    D:\gfortran\james\GetWindowsDirectory>type gwdw.f90
    module winstuff
    use ISO_C_BINDING
    implicit none
    interface
    function GetWindowsDirectoryW(lpBuffer, uSize) bind(C,name="GetWindowsDirectoryW")
    import
    implicit none
    !GCC$ ATTRIBUTES STDCALL:: GetWindowsDirectoryW
    !DEC$ ATTRIBUTES STDCALL:: GetWindowsDirectoryW
    integer(C_INT) GetWindowsDirectoryW
    integer(C_INT16_T) lpBuffer(*)
    integer(C_INT), value:: uSize
    end function GetWindowsDirectoryW
    end interface
    end module winstuff

    program test
    use winstuff
    implicit none
    integer(C_INT) uSize
    integer(C_INT16_T), allocatable :: lpBuffer(:)
    integer(C_INT) res

    uSize = 0
    allocate(lpBuffer(0))
    res = GetWindowsDirectoryW(lpBuffer,uSize)
    if(res == 0) write(*,*) 'GetWindowsDirectoryW failed'
    uSize = res
    deallocate(lpBuffer)
    allocate(lpBuffer(uSize))
    res = GetWindowsDirectoryW(lpBuffer,uSize)
    if(res == 0) write(*,*) 'GetWindowsDirectoryW failed again'
    write(*,'(*(g0))') char(lpBuffer)
    end program test

    D:\gfortran\james\GetWindowsDirectory>gfortran gwdw.f90 -ogwdw

    D:\gfortran\james\GetWindowsDirectory>gwdw
    C:\Windows

    Did in fact just work.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Gary Scott@21:1/5 to Lynn McGuire on Tue Feb 1 08:10:05 2022
    On 1/31/2022 2:03 PM, Lynn McGuire wrote:
    Does anyone know how to call wide UTF-16 Win32 functions in a Intel
    Fortran Win32 DLL ?  The linker in Visual Studio cannot link in GetWindowsDirectoryW that I am calling in my C code in the Ifort Win32
    DLL.  I am going to use the LoadLibrary route but I really do not want
    to do this unless I have to.

    Thanks,
    Lynn
    If not zero, it's pretty darn close to zero the number of win32
    functions that you CAN'T call with Intel Fortran and the prior lineage
    (CVF, DVF)...even before introduction of the BIND mechanism.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From eugene_epshteyn@yahoo.com@21:1/5 to Lynn McGuire on Tue Feb 1 06:56:52 2022
    On Monday, January 31, 2022 at 3:04:02 PM UTC-5, Lynn McGuire wrote:
    The linker in Visual Studio cannot link in
    GetWindowsDirectoryW that I am calling in my C code in the Ifort Win32
    DLL.

    Hi Lynn,

    What do you mean by "calling in my C code"? Do you have your Fortran code calling your C code, and from that C code you call GetWindowsDirectoryW?

    Thanks,

    Eugene

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lynn McGuire@21:1/5 to Gary Scott on Tue Feb 1 13:22:13 2022
    On 2/1/2022 8:10 AM, Gary Scott wrote:
    On 1/31/2022 2:03 PM, Lynn McGuire wrote:
    Does anyone know how to call wide UTF-16 Win32 functions in a Intel
    Fortran Win32 DLL ?  The linker in Visual Studio cannot link in
    GetWindowsDirectoryW that I am calling in my C code in the Ifort Win32
    DLL.  I am going to use the LoadLibrary route but I really do not want
    to do this unless I have to.

    Thanks,
    Lynn
    If not zero, it's pretty darn close to zero the number of win32
    functions that you CAN'T call with Intel Fortran and the prior lineage
    (CVF, DVF)...even before introduction of the BIND mechanism.

    Do you have a working example code for Intel Fortran ?

    Thanks,
    Lynn

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lynn McGuire@21:1/5 to James Van Buskirk on Tue Feb 1 13:21:31 2022
    On 2/1/2022 2:45 AM, James Van Buskirk wrote:
    "Lynn McGuire"  wrote in message news:st9fbe$igp$1@dont-email.me...

    Does anyone know how to call wide UTF-16 Win32 functions in a Intel
    Fortran Win32 DLL ?  The linker in Visual Studio cannot link in
    GetWindowsDirectoryW that I am calling in my C code in the Ifort Win32
    DLL.  I am going to use the LoadLibrary route but I really do not want
    to do this unless I have to.

    GetWindowsDirectoryW is in kernel32.dll so it should work with no
    problems. Indeed,

    D:\gfortran\james\GetWindowsDirectory>type gwdw.f90
    module winstuff
      use ISO_C_BINDING
      implicit none
      interface
         function GetWindowsDirectoryW(lpBuffer, uSize) bind(C,name="GetWindowsDirectoryW")
            import
            implicit none
    !GCC$ ATTRIBUTES STDCALL:: GetWindowsDirectoryW
    !DEC$ ATTRIBUTES STDCALL:: GetWindowsDirectoryW
            integer(C_INT) GetWindowsDirectoryW
            integer(C_INT16_T) lpBuffer(*)
            integer(C_INT), value:: uSize
         end function GetWindowsDirectoryW
      end interface
    end module winstuff

    program test
      use winstuff
      implicit none
      integer(C_INT) uSize
      integer(C_INT16_T), allocatable :: lpBuffer(:)
      integer(C_INT) res

      uSize = 0
      allocate(lpBuffer(0))
      res = GetWindowsDirectoryW(lpBuffer,uSize)
      if(res == 0) write(*,*) 'GetWindowsDirectoryW failed'
      uSize = res
      deallocate(lpBuffer)
      allocate(lpBuffer(uSize))
      res = GetWindowsDirectoryW(lpBuffer,uSize)
      if(res == 0) write(*,*) 'GetWindowsDirectoryW failed again'
      write(*,'(*(g0))') char(lpBuffer)
    end program test

    D:\gfortran\james\GetWindowsDirectory>gfortran gwdw.f90 -ogwdw

    D:\gfortran\james\GetWindowsDirectory>gwdw
    C:\Windows

    Did in fact just work.

    Thanks ! Very cool example !

    But this example is for gfortran and I am using Intel Fortran.

    My problem is that the linker in Intel Fortran is not linking in wide
    Win32 API functions. Looks like the linker in gfortran is working
    perfectly.

    Lynn

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lynn McGuire@21:1/5 to eugene_...@yahoo.com on Tue Feb 1 13:24:50 2022
    On 2/1/2022 8:56 AM, eugene_...@yahoo.com wrote:
    On Monday, January 31, 2022 at 3:04:02 PM UTC-5, Lynn McGuire wrote:
    The linker in Visual Studio cannot link in
    GetWindowsDirectoryW that I am calling in my C code in the Ifort Win32
    DLL.

    Hi Lynn,

    What do you mean by "calling in my C code"? Do you have your Fortran code calling your C code, and from that C code you call GetWindowsDirectoryW?

    Thanks,

    Eugene

    Yes, exactly. I use the same system code in C++ for my Fortran
    calculation engine and my C++ Win32 user interface.

    I have a function in C++ (with extern "C") that I call
    myGetWindowsDirectoryW ().

    Thanks,
    Lynn

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Gary Scott@21:1/5 to Lynn McGuire on Tue Feb 1 14:28:06 2022
    On 2/1/2022 1:22 PM, Lynn McGuire wrote:
    On 2/1/2022 8:10 AM, Gary Scott wrote:
    On 1/31/2022 2:03 PM, Lynn McGuire wrote:
    Does anyone know how to call wide UTF-16 Win32 functions in a Intel
    Fortran Win32 DLL ?  The linker in Visual Studio cannot link in
    GetWindowsDirectoryW that I am calling in my C code in the Ifort
    Win32 DLL.  I am going to use the LoadLibrary route but I really do
    not want to do this unless I have to.

    Thanks,
    Lynn
    If not zero, it's pretty darn close to zero the number of win32
    functions that you CAN'T call with Intel Fortran and the prior lineage
    (CVF, DVF)...even before introduction of the BIND mechanism.

    Do you have a working example code for Intel Fortran ?

    Thanks,
    Lynn
    It appears to me that James' example is written for compatibility with
    both GCC and Intel. Unfortunately, my install is corrupted at the
    moment and I'm not in near term need to fix it in order to check.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Steve Lionel@21:1/5 to Lynn McGuire on Tue Feb 1 16:29:15 2022
    On 2/1/2022 2:21 PM, Lynn McGuire wrote:
    Thanks !  Very cool example !

    But this example is for gfortran and I am using Intel Fortran.

    My problem is that the linker in Intel Fortran is not linking in wide
    Win32 API functions.  Looks like the linker in gfortran is working perfectly.

    It works fine for me in Intel Fortran:

    D:\Projects>ifort t.f90
    Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running
    on Intel(R) 64, Version 2021.5.0 Build 20211109_000000
    Copyright (C) 1985-2021 Intel Corporation. All rights reserved.

    Microsoft (R) Incremental Linker Version 14.29.30139.0
    Copyright (C) Microsoft Corporation. All rights reserved.

    -out:t.exe
    -subsystem:console
    t.obj

    D:\Projects>t.exe
    C:\WINDOWS

    The routine is found in kernel32.lib, which should be searched by
    default. You can always add kernel32.lib as an additional library to be searched, or add "USE KERNEL32".

    --
    Steve Lionel
    ISO/IEC JTC1/SC22/WG5 (Fortran) Convenor
    Retired Intel Fortran developer/support
    Email: firstname at firstnamelastname dot com
    Twitter: @DoctorFortran
    LinkedIn: https://www.linkedin.com/in/stevelionel
    Blog: https://stevelionel.com/drfortran
    WG5: https://wg5-fortran.org

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lynn McGuire@21:1/5 to Steve Lionel on Tue Feb 1 19:59:48 2022
    On 2/1/2022 3:29 PM, Steve Lionel wrote:
    On 2/1/2022 2:21 PM, Lynn McGuire wrote:
    Thanks !  Very cool example !

    But this example is for gfortran and I am using Intel Fortran.

    My problem is that the linker in Intel Fortran is not linking in wide
    Win32 API functions.  Looks like the linker in gfortran is working
    perfectly.

    It works fine for me in Intel Fortran:

    D:\Projects>ifort t.f90
    Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running
    on Intel(R) 64, Version 2021.5.0 Build 20211109_000000
    Copyright (C) 1985-2021 Intel Corporation.  All rights reserved.

    Microsoft (R) Incremental Linker Version 14.29.30139.0
    Copyright (C) Microsoft Corporation.  All rights reserved.

    -out:t.exe
    -subsystem:console
    t.obj

    D:\Projects>t.exe
    C:\WINDOWS

    The routine is found in kernel32.lib, which should be searched by
    default. You can always add kernel32.lib as an additional library to be searched, or add "USE KERNEL32".

    Yup, I added "kernel32.lib Advapi32.lib user32.lib mpr.lib Ws2_32.lib"
    to the Additional Dependencies for the Win32 DLL options in Visual
    Studio 2019.

    I think that I am having a very strange problem here. Maybe some weird
    Fortran to C interaction.

    BTW, were you using 32 bit Intel Fortran or 64 bit Intel Fortran ?

    Thanks,
    Lynn

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Steve Lionel@21:1/5 to Lynn McGuire on Wed Feb 2 12:23:30 2022
    On 2/1/2022 8:59 PM, Lynn McGuire wrote:
    BTW, were you using 32 bit Intel Fortran or 64 bit Intel Fortran ?

    I tried both - same result.

    --
    Steve Lionel
    ISO/IEC JTC1/SC22/WG5 (Fortran) Convenor
    Retired Intel Fortran developer/support
    Email: firstname at firstnamelastname dot com
    Twitter: @DoctorFortran
    LinkedIn: https://www.linkedin.com/in/stevelionel
    Blog: https://stevelionel.com/drfortran
    WG5: https://wg5-fortran.org

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lynn McGuire@21:1/5 to Steve Lionel on Wed Feb 2 13:05:34 2022
    On 2/2/2022 11:23 AM, Steve Lionel wrote:
    On 2/1/2022 8:59 PM, Lynn McGuire wrote:
    BTW, were you using 32 bit Intel Fortran or 64 bit Intel Fortran ?

    I tried both - same result.

    Thanks !

    I need to modify the sample code above to add C/C++ code to see if that variation works. I have combed Visual Studio 2019 to see if I have an incorrect setting somewhere.

    BTW, my Win32 DLL has over 2,000 Fortran subroutines and 100 C/C++
    functions. It is my small Fortran DLL, the other DLL has over 5,000
    Fortran subroutines with the same C/C++ functions.

    Lynn

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Steve Lionel@21:1/5 to Lynn McGuire on Wed Feb 2 16:42:41 2022
    On 2/2/2022 2:05 PM, Lynn McGuire wrote:
    I need to modify the sample code above to add C/C++ code to see if that variation works.  I have combed Visual Studio 2019 to see if I have an incorrect setting somewhere.

    You need to link to the appropriate Windows API import libraries. If you
    use the Intel modules, such as KERNEL32, they contain directives to do
    this. If you're not using the modules, and linking to DLL libraries,
    you'll need to add references to the appropriate Windows API library.
    Tip: Near the bottom of each Microsoft page describing an API function
    is a mention of which import library it comes from.

    --
    Steve Lionel
    ISO/IEC JTC1/SC22/WG5 (Fortran) Convenor
    Retired Intel Fortran developer/support
    Email: firstname at firstnamelastname dot com
    Twitter: @DoctorFortran
    LinkedIn: https://www.linkedin.com/in/stevelionel
    Blog: https://stevelionel.com/drfortran
    WG5: https://wg5-fortran.org

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From eugene_epshteyn@yahoo.com@21:1/5 to All on Thu Feb 3 20:04:02 2022
    Lynn,

    It's possible that C++ code picks up the wrong declaration of GetWindowsDirectoryW(). For example, if C++ compiler cannot find declaration of this function, it will assume it's a function that returns int and will deduce the parameters based on the
    passed arguments. (Some compilers would output a warning for this case.) In C++ code, lacking extern "C" declaration, the compiler will mangle the function name based on the parameters. If the compiler deduced the parameters incorrectly, then it'll still
    emit the function call, but the linker may not find the exact definition and complain about it. (The linker may even find the original GetWindowsDirectoryW() function in the import library, but it will assume you were trying to call some sort of
    overloaded GetWindowsDirectoryW() function.)

    I recommend that you check that you include the right header file in the .cpp source file that calls GetWindowsDirectoryW() and also check that correctly typed arguments are passed to this function call.

    Thanks,

    Eugene

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lynn McGuire@21:1/5 to eugene_...@yahoo.com on Fri Feb 4 16:38:27 2022
    On 2/3/2022 10:04 PM, eugene_...@yahoo.com wrote:
    Lynn,

    It's possible that C++ code picks up the wrong declaration of GetWindowsDirectoryW(). For example, if C++ compiler cannot find declaration of this function, it will assume it's a function that returns int and will deduce the parameters based on the
    passed arguments. (Some compilers would output a warning for this case.) In C++ code, lacking extern "C" declaration, the compiler will mangle the function name based on the parameters. If the compiler deduced the parameters incorrectly, then it'll still
    emit the function call, but the linker may not find the exact definition and complain about it. (The linker may even find the original GetWindowsDirectoryW() function in the import library, but it will assume you were trying to call some sort of
    overloaded GetWindowsDirectoryW() function.)

    I recommend that you check that you include the right header file in the .cpp source file that calls GetWindowsDirectoryW() and also check that correctly typed arguments are passed to this function call.

    Thanks,

    Eugene

    I am getting some weird interactions with Visual Studio 2019. I am
    going to to write a script to do a total build of my win32 dll and exe
    files to make sure that VS 2019 is not messing with me. BTW, this is
    how I build with the Watcom compilers and linker, works well.

    Thanks,
    Lynn

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James Van Buskirk@21:1/5 to Lynn McGuire on Sat Feb 5 03:38:24 2022
    "Lynn McGuire" wrote in message news:stk9t3$l0u$1@dont-email.me...

    I am getting some weird interactions with Visual Studio 2019. I am going
    to to write a script to do a total build of my win32 dll and exe files to make sure that VS 2019 is not messing with me. BTW, this is how I build
    with the Watcom compilers and linker, works well.

    Microsoft assumes that you will only use 8-bit characters or 16-bit
    characters in a project. Fortran makes it easier to mix things up with
    its KINDs instead of the C convention of giving every KIND of integer
    its own name. There is a problem in that C++ wants to mangle names
    unless you tell it not to. You can tell if name mangling is occurring
    by looking at the *.o or *.obj file with notepad.

    My example:

    D:\gfortran\james\GetWindowsDirectory>type GWD.h
    // GWD.h

    #ifndef GWD_H
    #define GWD_H
    #include <WinDef.h>
    extern "C" __stdcall UINT GetWindowsDirectoryW(LPWSTR lpBuffer, UINT uSize); extern "C" void cpp_gwd(LPWSTR* myBuffer, UINT* mySize);
    extern "C" void deallocate_me(LPWSTR* myBuffer);
    #endif

    D:\gfortran\james\GetWindowsDirectory>type GWD2.cpp
    // GWD2.cpp
    #include "GWD.h"

    void cpp_gwd(LPWSTR* myBuffer, UINT* mySize)
    {
    UINT res;
    *mySize = 0;
    *myBuffer = new wchar_t[0];
    res = GetWindowsDirectoryW(*myBuffer, *mySize);
    if(res == 0)
    {
    *mySize = 0;
    delete[] *myBuffer;
    return;
    }
    *mySize = res;
    delete[] *myBuffer;
    *myBuffer = new wchar_t[*mySize];
    res = GetWindowsDirectoryW(*myBuffer, *mySize);
    if(res == 0)
    {
    *mySize = 0;
    delete[] *myBuffer;
    return;
    }
    return;
    }

    void deallocate_me(LPWSTR* myBuffer)
    {
    delete[] *myBuffer;
    }

    D:\gfortran\james\GetWindowsDirectory>g++ -Wall -c GWD2.cpp

    D:\gfortran\james\GetWindowsDirectory>type GWD1.f90
    ! GWD1.f90
    module GWDstuff
    use ISO_C_BINDING
    implicit none
    interface
    subroutine cpp_gwd(myBuffer,mySize) bind(C,name='cpp_gwd')
    import
    implicit none
    type(C_PTR) myBuffer
    integer(C_INT) mySize
    end subroutine cpp_gwd
    end interface
    interface
    subroutine deallocate_me(myBuffer) bind(C,name='deallocate_me')
    import
    implicit none
    type(C_PTR) myBuffer
    end subroutine deallocate_me
    end interface
    end module GWDstuff

    program test
    use GWDstuff
    implicit none
    integer(C_INT) mySize
    type(C_PTR) myBuffer
    integer(C_INT16_T), pointer :: string(:)

    call cpp_gwd(myBuffer,mySize)
    if(mySize == 0) then
    error stop 'GetWindowsDirectoryW failed'
    end if
    call C_F_POINTER(myBuffer, string, [mySize])
    write(*,'(*(g0))') char(string)
    call deallocate_me(myBuffer)
    nullify(string)
    end program test

    D:\gfortran\james\GetWindowsDirectory>gfortran -Wall GWD1.f90
    GWD2.o -lstdc++ -o
    GWD1

    D:\gfortran\james\GetWindowsDirectory>GWD1
    C:\Windows

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lynn McGuire@21:1/5 to James Van Buskirk on Sat Feb 5 23:08:20 2022
    On 2/5/2022 4:38 AM, James Van Buskirk wrote:
    "Lynn McGuire"  wrote in message news:stk9t3$l0u$1@dont-email.me...

    I am getting some weird interactions with Visual Studio 2019.  I am
    going to to write a script to do a total build of my win32 dll and exe
    files to make sure that VS 2019 is not messing with me.  BTW, this is
    how I build with the Watcom compilers and linker, works well.

    Microsoft assumes that you will only use 8-bit characters or 16-bit characters in a project. Fortran makes it easier to mix things up with
    its KINDs instead of the C convention of giving every KIND of integer
    its own name. There is a problem in that C++ wants to mangle names
    unless you tell it not to. You can tell if name mangling is occurring
    by looking at the *.o or *.obj file with notepad.

    My example:

    D:\gfortran\james\GetWindowsDirectory>type GWD.h
    // GWD.h

    #ifndef GWD_H
    #define GWD_H
    #include <WinDef.h>
    extern "C" __stdcall UINT GetWindowsDirectoryW(LPWSTR lpBuffer, UINT
    uSize);
    extern "C" void cpp_gwd(LPWSTR* myBuffer, UINT* mySize);
    extern "C" void deallocate_me(LPWSTR* myBuffer);
    #endif

    D:\gfortran\james\GetWindowsDirectory>type GWD2.cpp
    // GWD2.cpp
    #include "GWD.h"

    void cpp_gwd(LPWSTR* myBuffer, UINT* mySize)
    {
      UINT res;
      *mySize = 0;
      *myBuffer = new wchar_t[0];
      res = GetWindowsDirectoryW(*myBuffer, *mySize);
      if(res == 0)
      {
         *mySize = 0;
         delete[] *myBuffer;
         return;
      }
      *mySize = res;
      delete[] *myBuffer;
      *myBuffer = new wchar_t[*mySize];
      res = GetWindowsDirectoryW(*myBuffer, *mySize);
      if(res == 0)
      {
         *mySize = 0;
         delete[] *myBuffer;
         return;
      }
      return;
    }

    void deallocate_me(LPWSTR* myBuffer)
    {
      delete[] *myBuffer;
    }

    D:\gfortran\james\GetWindowsDirectory>g++ -Wall -c GWD2.cpp

    D:\gfortran\james\GetWindowsDirectory>type GWD1.f90
    ! GWD1.f90
    module GWDstuff
      use ISO_C_BINDING
      implicit none
      interface
         subroutine cpp_gwd(myBuffer,mySize) bind(C,name='cpp_gwd')
            import
            implicit none
            type(C_PTR) myBuffer
            integer(C_INT) mySize
         end subroutine cpp_gwd
      end interface
      interface
         subroutine deallocate_me(myBuffer) bind(C,name='deallocate_me')
            import
            implicit none
            type(C_PTR) myBuffer
         end subroutine deallocate_me
      end interface
    end module GWDstuff

    program test
      use GWDstuff
      implicit none
      integer(C_INT) mySize
      type(C_PTR) myBuffer
      integer(C_INT16_T), pointer :: string(:)

      call cpp_gwd(myBuffer,mySize)
      if(mySize == 0) then
         error stop 'GetWindowsDirectoryW failed'
      end if
      call C_F_POINTER(myBuffer, string, [mySize])
      write(*,'(*(g0))') char(string)
      call deallocate_me(myBuffer)
      nullify(string)
    end program test

    D:\gfortran\james\GetWindowsDirectory>gfortran -Wall GWD1.f90 GWD2.o
    -lstdc++ -o
    GWD1

    D:\gfortran\james\GetWindowsDirectory>GWD1
    C:\Windows

    I need to try this code with Visual Studio and Intel Fortran.

    Thanks,
    Lynn

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lynn McGuire@21:1/5 to James Van Buskirk on Sun Feb 6 13:23:32 2022
    On 2/5/2022 4:38 AM, James Van Buskirk wrote:
    "Lynn McGuire"  wrote in message news:stk9t3$l0u$1@dont-email.me...

    I am getting some weird interactions with Visual Studio 2019.  I am
    going to to write a script to do a total build of my win32 dll and exe
    files to make sure that VS 2019 is not messing with me.  BTW, this is
    how I build with the Watcom compilers and linker, works well.

    Microsoft assumes that you will only use 8-bit characters or 16-bit characters in a project. Fortran makes it easier to mix things up with
    its KINDs instead of the C convention of giving every KIND of integer
    its own name. There is a problem in that C++ wants to mangle names
    unless you tell it not to. You can tell if name mangling is occurring
    by looking at the *.o or *.obj file with notepad.

    My example:

    D:\gfortran\james\GetWindowsDirectory>type GWD.h
    // GWD.h

    #ifndef GWD_H
    #define GWD_H
    #include <WinDef.h>
    extern "C" __stdcall UINT GetWindowsDirectoryW(LPWSTR lpBuffer, UINT
    uSize);
    extern "C" void cpp_gwd(LPWSTR* myBuffer, UINT* mySize);
    extern "C" void deallocate_me(LPWSTR* myBuffer);
    #endif

    D:\gfortran\james\GetWindowsDirectory>type GWD2.cpp
    // GWD2.cpp
    #include "GWD.h"

    void cpp_gwd(LPWSTR* myBuffer, UINT* mySize)
    {
      UINT res;
      *mySize = 0;
      *myBuffer = new wchar_t[0];
      res = GetWindowsDirectoryW(*myBuffer, *mySize);
      if(res == 0)
      {
         *mySize = 0;
         delete[] *myBuffer;
         return;
      }
      *mySize = res;
      delete[] *myBuffer;
      *myBuffer = new wchar_t[*mySize];
      res = GetWindowsDirectoryW(*myBuffer, *mySize);
      if(res == 0)
      {
         *mySize = 0;
         delete[] *myBuffer;
         return;
      }
      return;
    }

    void deallocate_me(LPWSTR* myBuffer)
    {
      delete[] *myBuffer;
    }

    D:\gfortran\james\GetWindowsDirectory>g++ -Wall -c GWD2.cpp

    D:\gfortran\james\GetWindowsDirectory>type GWD1.f90
    ! GWD1.f90
    module GWDstuff
      use ISO_C_BINDING
      implicit none
      interface
         subroutine cpp_gwd(myBuffer,mySize) bind(C,name='cpp_gwd')
            import
            implicit none
            type(C_PTR) myBuffer
            integer(C_INT) mySize
         end subroutine cpp_gwd
      end interface
      interface
         subroutine deallocate_me(myBuffer) bind(C,name='deallocate_me')
            import
            implicit none
            type(C_PTR) myBuffer
         end subroutine deallocate_me
      end interface
    end module GWDstuff

    program test
      use GWDstuff
      implicit none
      integer(C_INT) mySize
      type(C_PTR) myBuffer
      integer(C_INT16_T), pointer :: string(:)

      call cpp_gwd(myBuffer,mySize)
      if(mySize == 0) then
         error stop 'GetWindowsDirectoryW failed'
      end if
      call C_F_POINTER(myBuffer, string, [mySize])
      write(*,'(*(g0))') char(string)
      call deallocate_me(myBuffer)
      nullify(string)
    end program test

    D:\gfortran\james\GetWindowsDirectory>gfortran -Wall GWD1.f90 GWD2.o
    -lstdc++ -o
    GWD1

    D:\gfortran\james\GetWindowsDirectory>GWD1
    C:\Windows

    Is there a very good visual debugger for GFortran ?

    The visual debugger in Simply Fortran is very limited. All breakpoints
    must be clicked to and set, you cannot just set the name of a subroutine
    to break at. Nor can you set which called instance of a subroutine to
    break (if I want to break at the 4,945th call of subroutine adbf).

    Thanks,
    Lynn

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James Van Buskirk@21:1/5 to Lynn McGuire on Sun Feb 6 13:46:39 2022
    "Lynn McGuire" wrote in message news:stp77m$ouv$1@dont-email.me...

    Is there a very good visual debugger for GFortran ?

    The visual debugger in Simply Fortran is very limited. All breakpoints
    must be clicked to and set, you cannot just set the name of a subroutine
    to break at. Nor can you set which called instance of a subroutine to
    break (if I want to break at the 4,945th call of subroutine adbf).

    I never use debuggers. You have to learn one for each compiler/OS
    combination, and since you can't know everything about everything
    you have to draw the line somewhere.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lynn McGuire@21:1/5 to James Van Buskirk on Sun Feb 6 16:43:25 2022
    On 2/6/2022 2:46 PM, James Van Buskirk wrote:
    "Lynn McGuire"  wrote in message news:stp77m$ouv$1@dont-email.me...
    Is there a very good visual debugger for GFortran ?

    The visual debugger in Simply Fortran is very limited.  All
    breakpoints must be clicked to and set, you cannot just set the name
    of a subroutine to break at.  Nor can you set which called instance of
    a subroutine to break (if I want to break at the 4,945th call of
    subroutine adbf).

    I never use debuggers. You have to learn one for each compiler/OS combination, and since you can't know everything about everything
    you have to draw the line somewhere.

    With 5,000+ subroutines and 850,000 lines of code, you either use print statements (the old mainframe days) or a visual debugger. I drastically
    prefer the visual debugger, it is why we have stayed with Watcom Fortran
    all these years. There is never a print statement in the right place.

    However, Windows 10 has broken the old debuggers by dropping support for hardware interrupts (or something like that). So, the Watcom debugger
    is broken unless I want to debug on my Windows 7 x64 PC. Just another
    reason to move on to a new Fortran environment.

    Lynn

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Gary Scott@21:1/5 to Lynn McGuire on Sun Feb 6 21:29:51 2022
    On 2/6/2022 4:43 PM, Lynn McGuire wrote:
    On 2/6/2022 2:46 PM, James Van Buskirk wrote:
    "Lynn McGuire"  wrote in message news:stp77m$ouv$1@dont-email.me...
    Is there a very good visual debugger for GFortran ?

    The visual debugger in Simply Fortran is very limited.  All
    breakpoints must be clicked to and set, you cannot just set the name
    of a subroutine to break at.  Nor can you set which called instance
    of a subroutine to break (if I want to break at the 4,945th call of
    subroutine adbf).

    I never use debuggers. You have to learn one for each compiler/OS
    combination, and since you can't know everything about everything
    you have to draw the line somewhere.

    With 5,000+ subroutines and 850,000 lines of code, you either use print statements (the old mainframe days) or a visual debugger.  I drastically prefer the visual debugger, it is why we have stayed with Watcom Fortran
    all these years.  There is never a print statement in the right place.

    However, Windows 10 has broken the old debuggers by dropping support for hardware interrupts (or something like that).  So, the Watcom debugger
    is broken unless I want to debug on my Windows 7 x64 PC.  Just another reason to move on to a new Fortran environment.

    Lynn
    You can still use hardware interrupts, they've simply made it as
    difficult as they possibly could.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From eugene_epshteyn@yahoo.com@21:1/5 to All on Mon Feb 7 05:47:53 2022
    "Lynn McGuire" wrote:
    Is there a very good visual debugger for GFortran ?

    There's Codelite IDE, which has Windows and Linux ports: https://codelite.org/

    On Linux, it integrates will with gdb: https://docs.codelite.org/debuggers/gdb/

    I haven't tried gdb integration on Windows, but in theory you can tell Codelite where to find compiler and gdb and it should "just work". Codelite docs do mention the limitation of debugging code in shared libraries with gdb and recommend using Intel
    debugger: https://wiki.codelite.org/pmwiki.php/Main/IntelDebugger

    If you use Cygwin and don't mind the hassle of installing Cygwin X libraries and X server, you could always run something like ddd: https://www.gnu.org/software/ddd/

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lynn McGuire@21:1/5 to eugene_...@yahoo.com on Mon Feb 7 14:49:56 2022
    On 2/7/2022 7:47 AM, eugene_...@yahoo.com wrote:
    "Lynn McGuire" wrote:
    Is there a very good visual debugger for GFortran ?

    There's Codelite IDE, which has Windows and Linux ports: https://codelite.org/

    On Linux, it integrates will with gdb: https://docs.codelite.org/debuggers/gdb/

    I haven't tried gdb integration on Windows, but in theory you can tell Codelite where to find compiler and gdb and it should "just work". Codelite docs do mention the limitation of debugging code in shared libraries with gdb and recommend using Intel
    debugger: https://wiki.codelite.org/pmwiki.php/Main/IntelDebugger

    If you use Cygwin and don't mind the hassle of installing Cygwin X libraries and X server, you could always run something like ddd: https://www.gnu.org/software/ddd/

    The Codelite documention does not mention Fortran whatsoever which makes
    me wary.

    However, there is Code::Blocks which explicitly states "Code::Blocks is
    a free C/C++ and Fortran IDE built to meet the most demanding needs of
    its users. It is designed to be very extensible and fully
    configurable.". If I abandon Intel Fortran again (this is the third try
    in almost 20 years), I will try Code::Blocks.
    http://www.codeblocks.org/

    Thanks,
    Lynn

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)