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

Unresolved external symbols

Ashley_Weinstein
Beginner
7,476 Views
When I attempt to compile some legacy code I first get an error that the linker cannot find DFWIN.LIB (from CVF days). So I ignore that specific library. Then I get another file that's a problem too. So I walk down the line and ignore the libraries that it's looking for. Overall the following 5 libraries are ignored:

dfwin.lib, dfor.lib, libc.lib, dfconsol.lib, dfport.lib

I have the libraries the linker wants (from a computer that still has CVF 6.6c installed on it) and I added them into the project solution but this did not resolve the issue. It began to have duplicate definitions errors, between the CVF version of the file and IVF version of the file.

After ignoring all 5 libraries I get the following error below. To me it appears that the functions that PSWPTH is looking for are Fortran intrinsic functions and since this is legacy code these intrinsic functions must be from CVF.

Linking...
Creating temporary file "RSP1.rsp" with contents
[
 /OUT:"K:\\Pyrotec\\Software\\RSISimcon\\930680IVF\\RSIEFPSBASE\\Release\\EFPS6.exe" /INCREMENTAL:NO /NOLOGO /NODEFAULTLIB:"dfwin.lib" /NODEFAULTLIB:"dfor.lib" /NODEFAULTLIB:"libc.lib" /NODEFAULTLIB:"dfconsol.lib" /NODEFAULTLIB:"dfport.lib" /MANIFEST /MANIFESTFILE:"K:\\Pyrotec\\Software\\RSISimcon\\930680IVF\\RSIEFPSBASE\\Release\\EFPS6.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"Debug/EFPS6.pdb" /SUBSYSTEM:CONSOLE kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /MACHINE:I386 "Debug/RSIDECNFG.obj" "Debug/PYGERA.obj" "Debug/fbxdrv.obj" "Debug/PyrolmLink.obj" "Debug/RSISPY.obj" "Debug/EFPSVersionInfo.res" "K:\\Pyrotec\\Software\\RSISimcon\\930680IVF\\RSIEFPSBASE\\Release\\GUIlink.lib" "K:\\Pyrotec\\Software\\RSISimcon\\930680IVF\\RSIEFPSBASE\\slmpsw\\lsapiw32.lib" "K:\\Pyrotec\\Software\\RSISimcon\\930680IVF\\RSIEFPSBASE\\PASSWD.lib" "K:\\Pyrotec\\Software\\RSISimcon\\930680IVF\\RSIEFPSBASE\\Release\\GEN9306.lib" "K:\\Pyrotec\\Software\\RSISimcon\\930680IVF\\RSIEFPSBASE\\Release\\TLEX.lib" "K:\\Pyrotec\\Software\\RSISimcon\\930680IVF\\RSIEFPSBASE\\Release\\Flowsheet.lib" "K:\\Pyrotec\\Software\\RSISimcon\\930680IVF\\RSIEFPSBASE\\Release\\SPYRO6.lib" "K:\\Pyrotec\\Software\\RSISimcon\\930680IVF\\RSIEFPSBASE\\Release\\FIREBOX.lib" "K:\\Pyrotec\\Software\\RSISimcon\\930680IVF\\RSIEFPSBASE\\Release\\LMFAC.lib" "K:\\Pyrotec\\Software\\RSISimcon\\930680IVF\\RSIEFPSBASE\\Release\\CONVEC.lib" "K:\\Pyrotec\\Software\\RSISimcon\\930680IVF\\RSIEFPSBASE\\NLSECURE.lib" "K:\\Pyrotec\\Software\\RSISimcon\\930680IVF\\RSIEFPSBASE\\Release\\KIN9306.lib" "K:\\Pyrotec\\Software\\RSISimcon\\930680IVF\\RSIEFPSBASE\\Release\\AUXILL.lib" "k:\\Pyrotec\\Software\\RSISimcon\\930680IVF\\RSIEFPSBASE\\Debug\\EFPS6_lib.lib"
]
Creating command line "Link @"K:\\Pyrotec\\Software\\RSISimcon\\930680IVF\\RSIEFPSBASE\\Debug\\RSP1.rsp""

Link: executing 'link'
EFPS6_lib.lib(Pyrolm.obj) : warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/INCREMENTAL:NO' specification
LINK : warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs; use /NODEFAULTLIB:library
NLSECURE.lib(PSWPTH.OBJ) : error LNK2019: unresolved external symbol _GETENVQQ@16 referenced in function _PSWPTH
NLSECURE.lib(PSWPTH.OBJ) : error LNK2019: unresolved external symbol _for_f90_index@20 referenced in function _PSWPTH
NLSECURE.lib(PSWPTH.OBJ) : error LNK2019: unresolved external symbol _for_len_trim@8 referenced in function _PSWPTH
NLSECURE.lib(PSWPTH.OBJ) : error LNK2001: unresolved external symbol _for_len_trim@8
NLSECURE.lib(PSWPTH.OBJ) : error LNK2001: unresolved external symbol _for_len_trim@8
NLSECURE.lib(PSWPTH.OBJ) : error LNK2019: unresolved external symbol __OtsMoveMinimum referenced in function _PSWPTH
NLSECURE.lib(PSWPTH.OBJ) : error LNK2019: unresolved external symbol __OtsFill referenced in function _PSWPTH
NLSECURE.lib(PSWPTH.OBJ) : error LNK2019: unresolved external symbol _SPLITPATHQQ@40 referenced in function _PSWPTH
K:\\Pyrotec\\Software\\RSISimcon\\930680IVF\\RSIEFPSBASE\\Release\\EFPS6.exe : fatal error LNK1120: 6 unresolved externals


EFPS6 - 9 error(s), 4 warning(s)

So I look into the static library containing PSWPTH.f and I see that it's using DFWIN and using DFLIB. I comment both of those out, recompile the *.lib file and reinsert it into the main project. I compile and get the following:

Linking...
Creating temporary file "RSP1.rsp" with contents
[
 /OUT:"K:\\Pyrotec\\Software\\RSISimcon\\930680IVF\\RSIEFPSBASE\\Release\\EFPS6.exe" /INCREMENTAL:NO /NOLOGO /NODEFAULTLIB:"dfwin.lib" /NODEFAULTLIB:"dfor.lib" /NODEFAULTLIB:"libc.lib" /NODEFAULTLIB:"dfconsol.lib" /NODEFAULTLIB:"dfport.lib" /MANIFEST /MANIFESTFILE:"K:\\Pyrotec\\Software\\RSISimcon\\930680IVF\\RSIEFPSBASE\\Release\\EFPS6.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"Debug/EFPS6.pdb" /SUBSYSTEM:CONSOLE kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /MACHINE:I386 "Debug/RSIDECNFG.obj" "Debug/PYGERA.obj" "Debug/fbxdrv.obj" "Debug/PyrolmLink.obj" "Debug/RSISPY.obj" "Debug/EFPSVersionInfo.res" "K:\\Pyrotec\\Software\\RSISimcon\\930680IVF\\RSIEFPSBASE\\Release\\GUIlink.lib" "K:\\Pyrotec\\Software\\RSISimcon\\930680IVF\\RSIEFPSBASE\\slmpsw\\lsapiw32.lib" "K:\\Pyrotec\\Software\\RSISimcon\\930680IVF\\RSIEFPSBASE\\PASSWD.lib" "K:\\Pyrotec\\Software\\RSISimcon\\930680IVF\\RSIEFPSBASE\\Release\\GEN9306.lib" "K:\\Pyrotec\\Software\\RSISimcon\\930680IVF\\RSIEFPSBASE\\Release\\TLEX.lib" "K:\\Pyrotec\\Software\\RSISimcon\\930680IVF\\RSIEFPSBASE\\Release\\Flowsheet.lib" "K:\\Pyrotec\\Software\\RSISimcon\\930680IVF\\RSIEFPSBASE\\Release\\SPYRO6.lib" "K:\\Pyrotec\\Software\\RSISimcon\\930680IVF\\RSIEFPSBASE\\Release\\FIREBOX.lib" "K:\\Pyrotec\\Software\\RSISimcon\\930680IVF\\RSIEFPSBASE\\AUXILL\\Release\\AUXILL.lib" "K:\\Pyrotec\\Software\\RSISimcon\\930680IVF\\RSIEFPSBASE\\Release\\LMFAC.lib" "K:\\Pyrotec\\Software\\RSISimcon\\930680IVF\\RSIEFPSBASE\\Release\\CONVEC.lib" "K:\\Pyrotec\\Software\\RSISimcon\\930680IVF\\RSIEFPSBASE\\NLSECURE.lib" "K:\\Pyrotec\\Software\\RSISimcon\\930680IVF\\RSIEFPSBASE\\Release\\KIN9306.lib" "k:\\Pyrotec\\Software\\RSISimcon\\930680IVF\\RSIEFPSBASE\\Debug\\EFPS6_lib.lib"
]
Creating command line "Link @"K:\\Pyrotec\\Software\\RSISimcon\\930680IVF\\RSIEFPSBASE\\Debug\\RSP1.rsp""

Link: executing 'link'
EFPS6_lib.lib(Pyrolm.obj) : warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/INCREMENTAL:NO' specification
LINK : warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs; use /NODEFAULTLIB:library
AUXILL.lib(PSWPTH.obj) : error LNK2019: unresolved external symbol _GETENVQQ@16 referenced in function _PSWPTH
AUXILL.lib(PSWPTH.obj) : error LNK2019: unresolved external symbol _GETMODULEFILENAME@16 referenced in function _PSWPTH
AUXILL.lib(PSWPTH.obj) : error LNK2019: unresolved external symbol _SPLITPATHQQ@40 referenced in function _PSWPTH
K:\\Pyrotec\\Software\\RSISimcon\\930680IVF\\RSIEFPSBASE\\Release\\EFPS6.exe : fatal error LNK1120: 3 unresolved externals


EFPS6 - 4 error(s), 4 warning(s)

I toggled DFLIB on and off. Now I get all 9 original errors regardless. Any help would be appreciated!
0 Kudos
49 Replies
Ashley_Weinstein
Beginner
1,921 Views

I agree with you - the problem is stemming from the calling conventions. This is old CVF 6.6c legacy code that I am trying to update to IVF and MS2008+ environment. Besides some basic editing and programming my skills in this area are limited. Especially when it comes to dealing with the nuances of compilers and IDEs. If I had a better understanding/grasp of exactly what the calling conventions are doing perhaps that might help me to resolve this particular issue. Thanks!

0 Kudos
IanH
Honored Contributor III
1,921 Views
I'd strongly recommend (1).

(2) can perhaps be left for a rainy day, certainly one that comes after you getting a working build, though note that the general use of modules is something you should get up to speed with as soon as possible if you will be continuing to program in Fortran.

Compiler options (C and Fortran) can affect calling conventions; and the symbol names in error messages can give good hints as to where things are going wrong. Detailing both in your posts will help. Attaching the buildlog is even better as it gives that detail plus some insight into whether static libraries are being correctly included in the link step for a later project.
0 Kudos
Ashley_Weinstein
Beginner
1,921 Views
OK, as soon as I am able to get back to the programming swing of things I'll make the changes and see what happens. Thanks for your help!
0 Kudos
Ashley_Weinstein
Beginner
1,921 Views
Hi Ian, I'm reading up on Fortran interoperability with C thanks to your original suggestion. I have plenty of C to Fortran interfaces I need to update. Hopefully this starts to flesh out the errors in the build.
0 Kudos
Ashley_Weinstein
Beginner
1,921 Views
I have about 41 subroutines associated with the GUI that I have to apply modifications for C++/Fortran operability. This is gonna be fun!
0 Kudos
Ashley_Weinstein
Beginner
1,921 Views
Is the following code going to work? I'm mainly concerned with the declarations of integer, character and real variables and how they are passed/referenced between Fortran and C++. I'm looking at some online references and examples for interoperability code and I know that there are limitations. For example, for operability the length type parameter has to be omoitted or be specified by an initialization expression equal to one. So then is a variable defined as CHARACTER*120 x in a Fortran subroutine not passable to a C++ subroutine where the character variable is defined as char *x??

Here is what I have below...

In Fortran:

SUBROUTINE GUIINI(x, y)
IMPLICIT NONE
CHARACTER*120 x
CHARACTER*125 a
CHARACTER*4 y
INTEGER*4 b

INTERFACE
SUBROUTINE GUIINIC(x, y), BIND(C, NAME='GUIInit')
USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_INT, C_CHAR
IMPLICIT NONE
INTEGER(C_INT) :: b
CHARACTER(C_CHAR) :: x
END SUBROUTINE GUIINIC
END INTERFACE

END SUBROUTINE

SUBROUTINE GUINAP(FEED, VALUES)
IMPLICIT NONE
INTEGER*4 FEED
REAL*4 VALUES(*)

INTERFACE
SUBROUTINE GUINAPC, BIND(C, NAME='GUINaphtha')
USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_INT, C_FLOAT
IMPLICIT NONE
INTEGER(C_INT) :: FEED
REAL(C_FLOAT) :: VALUES
END SUBROUTINE
END INTERFACE

END SUBROUTINE

In C++:

void
GUIInit(char *x, int y)
{
char ghost[256];
FILE *OutFile;

memcpy(GUICase, x, (sizeof(char) * (strlen(x) + 1)));
...
}

void
GUINaphtha(int FeedNumber, float *Values)
{
...
}

0 Kudos
IanH
Honored Contributor III
1,921 Views
The fortran interface for a char parameter on the C side must be length 1. If you are passing a string, rather than a single character, then you declare the fortran CHARACTER argument that corresponds to the char* parameter as an explicit shape or assumed size array.

(When declaring such an interface in Fortran be mindful that the default type parameter for CHARACTER variables is the LEN parameter, not the KIND parameter. So CHARACTER(C_CHAR) is equivalent to CHARACTER(LEN=C_CHAR), not the intended CHARACTER(KIND=C_CHAR). This is a mistake that I only make myself a couple of dozen times an hour.)

Normally the actual argument that corresponds to an array dummy argument must also be an array. But there are some exceptions - and importantly one of them is for KIND=C_CHAR CHARACTER arguments (the exception also applies to default kind character, but in ifort's case the default kind is also KIND=C_CHAR). In this case the sequence of characters in the string that is the actual argument get associated with the single character elements of the array dummy argument in a sane way.

(In summary - while the declaration of the interface needs to be length 1, you can still pass strings (or the storage for strings) from Fortran to C with length greater than one.)

When you are passing strings (or the storage for a string) from C to Fortran it is messier - the string comes in as an array. Before you can use the familiar Fortran string intrinsics you typically need to associate or copy the array to a CHARACTER scalar with length > 1.

From your example I infer that the character x argument in GUI is to receive data from the C side (??). At the moment there are multiple issues - you are passing a length one scalar (one byte...) and by the looks of it you are trying to poke a whole C string into it (many bytes?). Further, the number of bytes to copy is determined by referencing the length of a string that is yet to be defined. A typical pattern here is to pass the string (with the argument declared as an array as discussed above) along with the length of storage that's available for that string, with the called function then being careful to only copy data into that available length. Perhaps clarify your intent for further advice.

Be mindful that C's default is to pass by value. Your integer arguments on the fortran side are missing the VALUE attribute. Some of your argument names in their type declarations don't match those in the argument list. Your Fortran subroutines don't show any calls to the procedures defined by the interface blocks either.

(Style comments - (particularly for new code...) try and get out of the habit of using numeric type declarations with the typename*kind syntax (i.e INTEGER*4). That's not standard Fortran syntax (though it is a very common extension) - instead use typename(kind) (i.e. INTEGER(4)). You are already doing this in the interface blocks - might as well be consistent. For character variables the CHARACTER*len form is deprecated in recent standards - consider using CHARACTER(len), being mindful of the len/kind issue mentioned above. Good practice beyond use of the correct syntax is to then specify your kinds via a parameter rather hard coding the value 4.

Consider adding INTENT spec's to your argument declarations, including those in the interface blocks. It's a simple but effective method of in-source documentation (particularly for those not intimately familiar with your code, such as those reading snippets posted in a forum, or yourself in two weeks time...) and helps the compiler's ability to do error checking too.)

(Your C++ is also missing extern "C" (perhaps it's flagged for the encompassing scope)?)

0 Kudos
Ashley_Weinstein
Beginner
1,921 Views
After examining the code I believe the intent is to create a Fortran call to a C++ subroutine as the code is written in C++ instead of Fortran, perform operations in C++, then pass the results back into Fortran. So I need to be able to handle both directions for passing information.

One question: Does the call to the C++ code defined in the Fortran INTERFACE block have to occur after and outside the INTERFACE block? Or does it need to be called inside the SUBROUTINE block that's inside the INTERFACE block? Or outside that SUBROUTINE block but inside the INTERFACE block?

Additionally, if my understanding of what you said regarding the Fortran/C++ interface is correct, I'd like to summarize the following regarding passing character variables from Fortran to C++:

To pass a string from Fortran to C/C++ and then back into Fortran from a Fortran call, I would need to setup the following code:

In C++ (linkc.c):

CPlusProgramLink(char* stringc)
{...
stringc=stringc // "in life"
...}

In Fortran (linkf.f):

SUBROUTINE LINKPROGRAMF(STRING1) !STRING1 = "Tomorrow you will"
CHARACTER(120) STRING1
CHARACTER(30) STRING2
...
STRING2="find renewed vigor"
STRING1=STRING1 // STRING2
INTERFACE
SUBROUTINE LINKFPROGRAMC(STRINGC), BIND(C, NAME='CPlusProgramLink')
USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_CHAR
IMPLICIT NONE
CHARACTER(KIND=C_CHAR, LEN=120) :: STRING2
END SUBROUTINE
END INTERFACE

CALL LINKFPROGRAMC(STRING1)

!At this point STRING1 = "Tomorrow you will find renewed vigor in life"

Is what I coded above right??

Also I am trying to understand the extern "C" comment you are making; bear with me, I'm not familiar with this as I have not programmed much.

There are four files associated with this GUI code:

- GUILink.h
- GUIComponents.c
- GUILinkC.c
- GUILinkF.f

At the beginning of GUILinkC.c there are standard system #include statements followed by a:

#include "GUILink.h"

GUILink.h file has following format:

#ifndef _GUILINK_H
#define _GUILINK_H
... (code containing #defines, extern const char declarations, etc.)
#endif _GUILINK_H

Is this reference correctly coded? GUILink.h is a C++ header file so do I even need an extern "C" construct in GUILinkC.c for this??
0 Kudos
JVanB
Valued Contributor II
1,921 Views
There are a bunch of mistakes in your code sample.It looks like you are interfacing with C, not C++ (*.c vs *.cpp).Neither C nor C++ has a concatenation operator, but there is a strcat() function in C and strstream.h in C++. These require ASCII NUL termination on input to work sensibly and the output also gets a NUL. In your Fortran code the input variable STRING1 has a fixed LEN of 120. Many think it better to get the LEN from the caller and test to make sure that it's long enough, as I do below. Also your interface block is out of place: it must be up among the specification statements of subroutine LINKPROGRAMF. Your interface body has the wrong name (STRING2 instead of STRINGC) for the declaration of the dummy argument and it has a non-unit LEN.I have fixed that up and made it an assumed-size array. Fortran does not trim strings on concatenation so the line
STRING1=STRING1//STRING2
actually does nothing. Also the C function will need ASCII NUL termination so I fixed that up. Finally Fortran will have to search for the NUL to know how long C thinks the string passed back actually is. Written as a Fortran main program and a C function I get:

[bash]#include CPlusProgramLink(char* stringc) { strcat(stringc," in life"); } [/bash]
[bash] program test IMPLICIT NONE character(120) STRINGin STRINGin = 'Tomorrow you will' call LINKPROGRAMF(STRINGin) end program test SUBROUTINE LINKPROGRAMF(STRING1) !STRING1 = "Tomorrow you will" IMPLICIT NONE CHARACTER(*) STRING1 CHARACTER(30) STRING2 integer, parameter :: string1len = 120 INTERFACE SUBROUTINE LINKFPROGRAMC(STRINGC) & & BIND(C, NAME='CPlusProgramLink') USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_CHAR IMPLICIT NONE CHARACTER(KIND=C_CHAR, LEN=1) :: STRINGC(*) END SUBROUTINE END INTERFACE if(len(STRING1) < string1len) then write(*,'(3(a,i0))') 'LEN(STRING1) = ', & & len(STRING1),' < ',string1len,'. Aborting' end if STRING2="find renewed vigor" STRING1=trim(STRING1) // ' ' // trim(STRING2) // achar(0) CALL LINKFPROGRAMC(STRING1) write(*,'(a)') STRING1(1:index(STRING1,achar(0))-1) end subroutine LINKPROGRAMF



!This looks poorly formatted but copy to clipboard seems to work OK.




[/bash]
0 Kudos
Ashley_Weinstein
Beginner
1,921 Views
Thanks a bunch for showing me the ins and outs of setting up the interface. I hastily put together that example and I haven't programmed in C (1 college course) in 11 years. My Fortran is fairly basic as well. I look up what I need when I need it and I don't need to program very often at all =p one more thing... what is ASCII NUL termination and how did you fix that up??

EDIT: I think I understand what you mean by ASCII NUL termination. Basically there is no equivalence statement when you use strcat() function (i.e. string2 = strcat(string1," in life"); is not a proper statement. So you simply code the strcat(string1," in life"); as such.

EDIT2: Why is it a problem if the length of string1 is less than the length specified in stringllen?? Shouldn't it be a problem if the length of string1 is longer then stringllen??
0 Kudos
Ashley_Weinstein
Beginner
1,921 Views
I am getting the same error on all of my Fortran INTERFACE SUBROUTINE declaration lines.

For example:

Line 50: INTERFACE
Line 51: SUBROUTINE GUIINIC(NAME, VER); BIND(C, NAME='GUIInit')

Error 1 error #5082: Syntax error, found END-OF-STATEMENT when expecting one of: :: / C:\...\GUILinkF.f 51

Any ideas as to what is wrong with the syntax??

0 Kudos
Steven_L_Intel1
Employee
1,921 Views
You have a semicolon before BIND. Take it out.
0 Kudos
Ashley_Weinstein
Beginner
1,921 Views
Thanks...

I originally had commas instead of semicolons before BIND but that was giving me the following error:

Error 1 error #5082: Syntax error, found ',' when expecting one of: ; K:\Pyrotec\Software\RSISimcon\930680IVF\EFPSBaseLib\GUIlink\GUILinkF.f 51

Now that I don't have any characters in between these errors are gone. I got led down the wrong path by several online references that had commas or semicolons before the BIND statement.

0 Kudos
Steven_L_Intel1
Employee
1,921 Views
BIND can be a statement, but in this context it's sort of an attribute of the subroutine declaration. As a statement, it can be used only to specify variables and commons, not procedures, derived types or enumerators.
0 Kudos
Ashley_Weinstein
Beginner
1,921 Views
Steve, thanks for the clarification on BIND.

BTW I'm so happy now, the code is now compiling properly after I made the modifications suggested by several of the posts above to the old legacy Fortran/C interfacing code.

Thanks everyone for your help =)

EDIT: I jumped to conclusions too fast... now I'm back to the unresolved external symbol problem again for all Fortran/C interfaces...

Error 1 error LNK2019: unresolved external symbol _GUIInit referenced in function _GUIINI EFPS68_lib.lib(GUILinkF.obj)

The linker is unable to find the C subroutines defined by the INTERFACE blocks =(
0 Kudos
Ashley_Weinstein
Beginner
1,921 Views
I figured out the problem.

I had to set Link Library Dependencies to 'Yes' Under project Configuration Properties => Librarian => Link Library Dependencies.

Now I have some new errors:

Error 135 error LNK2005: _fclose already defined in LIBCMTD.lib(fclose.obj) MSVCRTD.lib(MSVCR90D.dll)
Error 136 error LNK2005: _fprintf already defined in LIBCMTD.lib(fprintf.obj) MSVCRTD.lib(MSVCR90D.dll)
Error 137 error LNK2005: _fopen already defined in LIBCMTD.lib(fopen.obj) MSVCRTD.lib(MSVCR90D.dll)
Error 138 error LNK2005: _sprintf already defined in LIBCMTD.lib(sprintf.obj) MSVCRTD.lib(MSVCR90D.dll)
Error 139 error LNK2005: _free already defined in LIBCMTD.lib(dbgfree.obj) MSVCRTD.lib(MSVCR90D.dll)
Error 140 error LNK2005: _realloc already defined in LIBCMTD.lib(dbgrealloc.obj) MSVCRTD.lib(MSVCR90D.dll)
Error 141 error LNK2005: _malloc already defined in LIBCMTD.lib(dbgmalloc.obj) MSVCRTD.lib(MSVCR90D.dll)
Error 142 error LNK2005: _printf already defined in LIBCMTD.lib(printf.obj) MSVCRTD.lib(MSVCR90D.dll)
Error 143 error LNK2005: ___iob_func already defined in LIBCMTD.lib(_file.obj) MSVCRTD.lib(MSVCR90D.dll)
Error 144 error LNK2005: _strtok already defined in LIBCMTD.lib(strtok.obj) MSVCRTD.lib(MSVCR90D.dll)
Error 145 error LNK2005: _strchr already defined in LIBCMTD.lib(strchr.obj) MSVCRTD.lib(MSVCR90D.dll)
Error 146 error LNK2005: "private: __thiscall type_info::type_info(class type_info const &)" (??0type_info@@AAE@ABV0@@Z) already defined in LIBCMTD.lib(typinfo.obj) MSVCRTD.lib(ti_inst.obj)
Error 147 error LNK2005: "private: class type_info & __thiscall type_info::operator=(class type_info const &)" (??4type_info@@AAEAAV0@ABV0@@Z) already defined in LIBCMTD.lib(typinfo.obj) MSVCRTD.lib(ti_inst.obj)

Any ideas?? It's amazing how stubborn the linker can be. Of course it would help immensely if I did understand the ins and outs of all these project options.
0 Kudos
Steven_L_Intel1
Employee
1,921 Views
You have "Mixed C Library Syndrome". Make sure that all the projects in the solution, and any outside library you link against, are compiled using the same setting for run-time libraries. LIBCMTD means one project is set to use the static debug libraries (probably the Fortran project as that is default), and MSVCRTD means another is set to use the DLL libraries (probably C/C++ as that is its default). In Fotran, this is under Libraries, in C++ under Code Generation.
0 Kudos
Ashley_Weinstein
Beginner
1,921 Views
Thanks!! I changed the C++ to use the static run-time libraries and that resolved the issue. Now I'm down to 10 errors remaining. Getting closer to the light at the end of the tunnel...
0 Kudos
Ashley_Weinstein
Beginner
1,921 Views
OK so now I've come complete circle and I have the same 6 unresolved externals that have plagued me from the very beginning... suffice to say I'm getting extremely frustrated with this. Are there any workarounds for the following functions below?? I would rather hard code substitutes for these functions in then to try and tinker around with the IDE anymore.
Generating non-SAFESEH image.
EFPS68_lib.lib(PSWPTH.OBJ) : error LNK2019: unresolved external symbol _GETENVQQ@16 referenced in function _PSWPTH
EFPS68_lib.lib(PSWPTH.OBJ) : error LNK2019: unresolved external symbol _for_f90_index@20 referenced in function _PSWPTH
EFPS68_lib.lib(PSWPTH.OBJ) : error LNK2019: unresolved external symbol _for_len_trim@8 referenced in function _PSWPTH
EFPS68_lib.lib(PSWPTH.OBJ) : error LNK2001: unresolved external symbol _for_len_trim@8
EFPS68_lib.lib(PSWPTH.OBJ) : error LNK2001: unresolved external symbol _for_len_trim@8
EFPS68_lib.lib(PSWPTH.OBJ) : error LNK2019: unresolved external symbol __OtsMoveMinimum referenced in function _PSWPTH
EFPS68_lib.lib(PSWPTH.OBJ) : error LNK2019: unresolved external symbol __OtsFill referenced in function _PSWPTH
EFPS68_lib.lib(PSWPTH.OBJ) : error LNK2019: unresolved external symbol _SPLITPATHQQ@40 referenced in function _PSWPTH
Debug\RSISPYEXE.exe : fatal error LNK1120: 6 unresolved externals

I fail to see where this project with regard to PSWPTH.OBJ is attempting to link with old CVF libraries. Firstly, PSWPTH.f is being recompiled to generate a NEW *.obj file. And I'm sorry, but the linker is obviously searching the correct *.lib files...
    Searching C:\Program Files\Intel\Composer XE 2011 SP1\compiler\lib\ia32\libifcoremdd.lib:
    Searching C:\Program Files\Intel\Composer XE 2011 SP1\compiler\lib\ia32\libifportmd.lib:
...and it finds other external references in these files...
Found _for_trim
        Referenced in RSISPY.obj
        Referenced in RSIDECNFG.obj
        Loaded libifcoremdd.lib(libifcoremdd.dll)

...and IT EVEN FINDS THE EXACT EXTERNAL SYMBOLS that supposedly are unresolved for PSWPTH.OBJ referenced in other object files...
 Found _for_len_trim
        Referenced in RSISPY.obj
        Referenced in RSIDECNFG.obj
        Referenced in EFPS68_lib.lib(GUILinkF.obj)
        Loaded libifcoremdd.lib(libifcoremdd.dll)

Found _for_f90_index Referenced in EFPS68_lib.lib(fbxdrvrsi.obj) Referenced in EFPS68_lib.lib(SPYRIN.obj) Loaded libifcoremdd.lib(libifcoremdd.dll)

...so HOW ON EARTH does this linker NOT KNOW that _for_len_trim is referenced in PSWPTH.obj AND loaded in libifcoremdd.lib when it has already been done for other ojbect files?!!?!??!?!?

I run /dumpbin /linkermember /out:"output filename" and get the following information...

libifcoremdd.lib
1414 public symbols
...
1A100 __imp__for_f90_index
1A100 _for_f90_index
...
17AD0 __imp__for_len_trim
17AD0 _for_len_trim
...
17F __imp__for_f90_index
...
17F _for_f90_index
...
127 __imp__for_len_trim
...
127 _for_len_trim


There has to be a solution for this... ... ...
0 Kudos
TimP
Honored Contributor III
1,896 Views
It looks like you are trying to mix /iface:cvf references with default ones. I doubt that is supported. I think it has been reiterated here that any old objects compiled with references to CVF or VS6 libraries must be rebuilt with recent compilers and ifort library replacements for DVF/CVF ones.
0 Kudos
Ashley_Weinstein
Beginner
1,896 Views
I understand that old objects compiled with references to CVF must be recompiled. I am recompiling this file in VS2008 with C#/C++ 2008 and IVF 12.1 and making a new *.obj file.

In PSWPTH.FOR I commented out DFWIN and DFLIB and replaced them with their IVF counterparts.

c USE DFWIN !04-10-2012
c USE DFLIB !04-10-2012
USE IFWIN !04-10-2012
USE IFCORE !04-10-2012
USE IFPORT !04-10-2012
USE IFQWIN !04-10-2012

Also I found that I had to add DFWIN.LIB and DFLIB.LIB to the "Ignore Specific Library" under "Librarian -> General" in the Fortran static library project and under "Linker -> Input" in the main Fortran executable even after commented out those lines. Somehow the project is still looking for them.

I have "Calling Convention" set to "Default" under "Fortran -> External Procedures" for both Fortran projects as well. Switching the calling convention from "Default" to "/iface:cvf" does not affect the linking errors one bit.

Right now I created a new Fortran *.f90 file and coded the exact same lines from PSWPTH.FOR into them, removed the old PSWPTH.FOR from the build and added in this new file with the same contents. Who knows, maybe the IDE will get tricked! Hahaha
0 Kudos
Reply