Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28866 Discussions

error LNK2001: unresolved external symbol for GDI32 functions

Mike-E2376
Beginner
989 Views

I am attempting to compile a Fortran Windows MDI application that was originally compiled with an older Watcom compiler.  Due to issues with the Watcom compiler, we have attempted to port the application to Intel Fortran with Visual Studio 2022.  We have resolved the differences in code and numerous compiler errors, but now have many linker errors that look like the following, primarily for GDI32 functions. 

d_cpick.obj : error LNK2001: unresolved external symbol _LINETO
d_3drwf.obj : error LNK2001: unresolved external symbol _LINETO
D_child.obj : error LNK2001: unresolved external symbol _LINETO
d_scale.obj : error LNK2001: unresolved external symbol _LINETO
D_line.obj : error LNK2001: unresolved external symbol _LINETO
d_paint.obj : error LNK2001: unresolved external symbol _SPRINTF
D_mem.obj : error LNK2001: unresolved external symbol _SPRINTF
d_symbol.obj : error LNK2001: unresolved external symbol _RECTANGLE
D_print.obj : error LNK2001: unresolved external symbol _RECTANGLE
d_paint.obj : error LNK2001: unresolved external symbol _RECTANGLE
D_note.obj : error LNK2001: unresolved external symbol _RECTANGLE
d_symbol.obj : error LNK2001: unresolved external symbol _SETTEXTCOLOR
D_avgcur.obj : error LNK2001: unresolved external symbol _SETTEXTCOLOR
D_filter.obj : error LNK2001: unresolved external symbol _SETTEXTCOLOR

Where the functions are called, we are using the "use gdi32" command and have included the gdi32.lib in the linker.  I am also including "advapi32.lib" "ws2_32.lib" in Additional Dependencies in the Linker Options.  I see these functions (with the exception of _sprintf, which is a stdio.h function from c) in the Intel gdi32.f90 module interfaces.  So what am I missing that the linker sees these as unresolved external symbols?

 

subroutine d_DrawContourPlot3DRWF( hdc, hdcAttr, rect, IsOverlay )
use ifwin
use dpltio
use dpltres
use d_custom
use d_misc
use m_3dplanes
use m_writetitles
use gdi32
implicit none

.

.

.

call LineTo(hdc,nint(Tri1(i).h(2)), nint(Tri1(i).v(2)) )

.

.

.

end subroutine

0 Kudos
1 Solution
Steve_Lionel
Honored Contributor III
963 Views

Replace "use ifwin" with "use ifwina". (You can also remove the use of gdi32, as it will be pulled in by ifwina (and ifwin). These are very old routines and have name conflicts with some other modules.  The following comments are in the source for ifwina (at the end of ifwin.f90):

! Because there are conflicts between the names of APIs in MSFWIN and 
! in MSFLIB, the affected APIs have been renamed to MSFWIN$... in 
! MSFWIN.  To use these Win32 APIs, either:
! a) Use the name as it appears here, such as MSFWIN$ARC instead of ARC
! b) Rename the MSFLIB version to something else (using a rename clause
!    on the USE statement), and then rename the MSFLIB version to the
!    original name.
! c) Only use what you need from MSFLIB with an ONLY clause on the USE
!    statement, and then use MSFWINA instead of MSFWIN (see below) which
!    has the renames for these APIs already done.
! d) The same as (c), but don't use MSFLIB at all if it can be avoided.
!
! Option (d) is often the easiest.

The names MSFWIN and MSFLIB come from Microsoft Fortran PowerStation. The module names were provided for compatibility by Digital Visual Fortran, then Compaq Visual Fortran and now Intel Fortran.

View solution in original post

0 Kudos
3 Replies
Mike-E2376
Beginner
965 Views

So I was looking at the gdi32.f90 file in "C:\Program Files (x86)\Intel\oneAPI\compiler\2023.1.0\windows\compiler\include" and noticed that the alias is being defined as follows:

!DEC$ ATTRIBUTES DEFAULT, STDCALL, DECORATE, ALIAS:'LineTo' :: MSFWIN$LineTo

and there is an explanation at the top of the ifwin.f90 file that states the following:

! Because there are conflicts between the names of APIs in MSFWIN and
! in MSFLIB, the affected APIs have been renamed to MSFWIN$... in
! MSFWIN. To use these Win32 APIs, either:
! a) Use the name as it appears here, such as MSFWIN$ARC instead of ARC
! b) Rename the MSFLIB version to something else (using a rename clause
! on the USE statement), and then rename the MSFLIB version to the
! original name.
! c) Only use what you need from MSFLIB with an ONLY clause on the USE
! statement, and then use MSFWINA instead of MSFWIN (see below) which
! has the renames for these APIs already done.
! d) The same as (c), but don't use MSFLIB at all if it can be avoided.
!
! Option (d) is often the easiest.
use ifwin, arc=>msfwin$arc, ellipse=>msfwin$ellipse, &
floodfill=>msfwin$floodfill, getbkcolor=>msfwin$getbkcolor, &
getpixel=>msfwin$getpixel, gettextcolor=>msfwin$gettextcolor, &
lineto=>msfwin$lineto, pie=>msfwin$pie, &
rectangle=>msfwin$rectangle, &
selectpalette=>msfwin$selectpalette, &
setbkcolor=>msfwin$setbkcolor, &
setpixel=>msfwin$setpixel, &
settextcolor=>msfwin$settextcolor, &
polygon=>msfwin$polygon
END MODULE IFWINA
!DEC$ ENDIF ! /* MSFWIN_ */

I'm not sure I completely understand options a, b, c, and d.  However, it seems that using msfwin$lineto instead of lineto resolves the linker error for the GDI functions.  I believe this is option a.

0 Kudos
Steve_Lionel
Honored Contributor III
964 Views

Replace "use ifwin" with "use ifwina". (You can also remove the use of gdi32, as it will be pulled in by ifwina (and ifwin). These are very old routines and have name conflicts with some other modules.  The following comments are in the source for ifwina (at the end of ifwin.f90):

! Because there are conflicts between the names of APIs in MSFWIN and 
! in MSFLIB, the affected APIs have been renamed to MSFWIN$... in 
! MSFWIN.  To use these Win32 APIs, either:
! a) Use the name as it appears here, such as MSFWIN$ARC instead of ARC
! b) Rename the MSFLIB version to something else (using a rename clause
!    on the USE statement), and then rename the MSFLIB version to the
!    original name.
! c) Only use what you need from MSFLIB with an ONLY clause on the USE
!    statement, and then use MSFWINA instead of MSFWIN (see below) which
!    has the renames for these APIs already done.
! d) The same as (c), but don't use MSFLIB at all if it can be avoided.
!
! Option (d) is often the easiest.

The names MSFWIN and MSFLIB come from Microsoft Fortran PowerStation. The module names were provided for compatibility by Digital Visual Fortran, then Compaq Visual Fortran and now Intel Fortran.

0 Kudos
Steve_Lionel
Honored Contributor III
947 Views

Yes, using the name MSFWIN$LINETO, etc., is option A. The other suggestions are mainly relevant if you're using another module, such as IFCORE, that defines different routines by the same names.

0 Kudos
Reply