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

Error when attempting to link C++ library

dktseng
Beginner
7,188 Views
Hi,

I am attempting to link a C++ library to Fortran. ADS_10p6.lib is a library I compiled from Microsoft Visual C++ .NET 2003 and I am using a Fortran code to call functions in that library. I am using Compaq Visual Fortran, not Intel, but this site is where I was told I could find support for CVF. I think that CVF is not compatible with Microsoft Visual C++ .NET 2003 and thats why Im getting errors, but I'm not 100% sure that's the problem.

I get the following errors when I compile the Fortran code:

ADS_10p6.lib(Ad_sensor.obj) : error LNK2001: unresolved external symbol __RTC_Shutdown
ADS_10p6.lib(Ad_sensor.obj) : error LNK2001: unresolved external symbol __RTC_InitBase
ADS_10p6.lib(Ad_sensor.obj) : error LNK2001: unresolved external symbol __RTC_CheckEsp
ADS_10p6.lib(Ad_sensor.obj) : error LNK2001: unresolved external symbol __RTC_UninitUse

What can I do to resolve these errors?

I also getthe follwingwarning that may have something to do with the errors:
LINK : warning LNK4098: defaultlib "LIBCD" conflicts with use of other libs; use /NODEFAULTLIB:library

Thank you.
0 Kudos
40 Replies
dktseng
Beginner
2,805 Views

Do you also have Microsoft Visual C++ installed? Mixed-language development is not supported unless you do. However, if you do, it should be sufficient to add the C++ compiled library to your Fortran project as if it were a source file.

I don't understand what you mean by ".NET libraries" - there is no such thing.

In CVF, I can go to Tools>Options>Directories and then put the .NET directories in the library files. I put the Microsoft Visual Studio .NET 2003Vc7lib directory in there. That got rid of the RTC errors. That's what I mean by the .NET libraries. I guess they are directories that call the library files.

I have Microsoft Visual Studio, Microsoft Visual Studio 8, and Microsoft Visual Studio .NET 2003 installed. Is that the same thing as Microsoft Visual C++?

Thanks.
0 Kudos
Steven_L_Intel1
Employee
2,805 Views

Ok - you mean that you added the Visual C++ libraries from "Visual Studio .NET 2003" to CVF. You should have been doing the linking from Visual Studio .NET 2003, but if that worked for you, fine.

I assume that each of the versions of Visual Studio you mention include Visual C++. Intel Visual Fortran integrates into Visual Studio .NET 2003 (VC7.1) and Visual Studio 2005 (VC8). If you open a Fortran project in those environments, the C++ library folder will automatically be in the libraries path and you don't need to do anything special.

What exactly is the problem you're having? In which environment are you doing the build? Please attach the buildlog.htm showing the whole build and link process, with the errors.
0 Kudos
dktseng
Beginner
2,805 Views

Ok - you mean that you added the Visual C++ libraries from "Visual Studio .NET 2003" to CVF. You should have been doing the linking from Visual Studio .NET 2003, but if that worked for you, fine.

I assume that each of the versions of Visual Studio you mention include Visual C++. Intel Visual Fortran integrates into Visual Studio .NET 2003 (VC7.1) and Visual Studio 2005 (VC8). If you open a Fortran project in those environments, the C++ library folder will automatically be in the libraries path and you don't need to do anything special.

What exactly is the problem you're having? In which environment are you doing the build? Please attach the buildlog.htm showing the whole build and link process, with the errors.

I attached the buildlog. I'm trying to figure out how to link a C++ static library I built called ADS_10p6.lib, which has the functions AD_SENSOR and AD_SYSTEM in it, to another fortran program using Intel fortran. When I build in fortran, it gives me the errors in the log.

Thanks.
0 Kudos
Steven_L_Intel1
Employee
2,805 Views
Ok, that's very different from the errors you listed earlier in this thread. Here, the linker isn't finding your C++ routines. How are these declared in C++? Show the routine headers. It's possible that you left out the 'extern "C"' prefix, or that you did not take into account the automatic upcasing of external symbols by Fortran.
0 Kudos
dktseng
Beginner
2,805 Views
Ok, that's very different from the errors you listed earlier in this thread. Here, the linker isn't finding your C++ routines. How are these declared in C++? Show the routine headers. It's possible that you left out the 'extern "C"' prefix, or that you did not take into account the automatic upcasing of external symbols by Fortran.

These errors are different than before because I was compiling with CVF and had already linked my C++ static library to it. Now that I have the Intel fortran compiler, I need to know how to link the same C++ library to it. In CVF, I can just go to Project>Settings>Link and add "../ADS_10p6.lib" and it would link that library. But I can't find the equivalent in the Intel compiler.

Thanks.
0 Kudos
Steven_L_Intel1
Employee
2,805 Views

Oh, I see. It's really the same - Project > Properties > Linker > Additional Dependencies

You can also just add the .LIB to the Fortran project as if it were a source file.
0 Kudos
Les_Neilson
Valued Contributor II
2,805 Views
Quoting - dktseng

These errors are different than before because I was compiling with CVF and had already linked my C++ static library to it. Now that I have the Intel fortran compiler, I need to know how to link the same C++ library to it. In CVF, I can just go to Project>Settings>Link and add "../ADS_10p6.lib" and it would link that library. But I can't find the equivalent in the Intel compiler.

Thanks.

Try :
Project->Properties-Configuration Properties->Linker

On the "General" panel there is an entry for Additional Library Directories (ie the PATHs you wish the linker to search)
And on the "Input" panel there is Additional Dependencies - this is where you add the libs you want linked into your application.

Hope this helps
Les

0 Kudos
dktseng
Beginner
2,805 Views
Quoting - Les Neilson

Try :
Project->Properties-Configuration Properties->Linker

On the "General" panel there is an entry for Additional Library Directories (ie the PATHs you wish the linker to search)
And on the "Input" panel there is Additional Dependencies - this is where you add the libs you want linked into your application.

Hope this helps
Les


I tried all of those but I get an error. It says it can't open the input file.

Does the directories need to be in a certain format when I add it? I have it as:
/LIBPATH and the Input Additional Dependencies as just: ADS_10p6.lib

When I do that, I get the error:
LINK fatal error LNK1181: cannot open input file 'ADS_10p6.lib'

Thanks for your help.
0 Kudos
Les_Neilson
Valued Contributor II
2,805 Views
Quoting - dktseng

I tried all of those but I get an error. It says it can't open the input file.

Does the directories need to be in a certain format when I add it? I have it as:
/LIBPATH and the Input Additional Dependencies as just: ADS_10p6.lib

When I do that, I get the error:
LINK fatal error LNK1181: cannot open input file 'ADS_10p6.lib'

Thanks for your help.


If ads_10p6.lib is in the directory z:sncdktseng_1codes then

Additional directories just needs to be z:sncdktseng_1codes

Les
0 Kudos
dktseng
Beginner
2,805 Views
Quoting - Les Neilson


If ads_10p6.lib is in the directory z:sncdktseng_1codes then

Additional directories just needs to be z:sncdktseng_1codes

Les

If I do that, I get the following errors:

AIR_SIM.obj error LNK2019: unresolved external symbol _AD_SENSOR referenced in function _MAIN__
AIR_SIM.obj error LNK2019: unresolved external symbol _AD_SYSTEM referenced in function _MAIN__
DebugAIR_SIM_executable_intel.exe fatal error LNK1120: 2 unresolved externals

where AD_SENSOR and AD_SYSTEM are functions inside of the ads_10p6.lib.
0 Kudos
Steven_L_Intel1
Employee
2,805 Views
Quoting - dktseng

where AD_SENSOR and AD_SYSTEM are functions inside of the ads_10p6.lib.

Are they really? How do you know?

Open a Fortran Build Environment command prompt window. "cd" to the folder containing the .lib and type the command:

dumpbin -symbols ads_10p6.lib > ads.txt

Attach the ads.txt file to a reply here.
0 Kudos
dktseng
Beginner
2,805 Views

Are they really? How do you know?

Open a Fortran Build Environment command prompt window. "cd" to the folder containing the .lib and type the command:

dumpbin -symbols ads_10p6.lib > ads.txt

Attach the ads.txt file to a reply here.

I know because when I linked the same library in CVF, it was able to link and call those functions. I've attached the txt file.

Thanks.
0 Kudos
Les_Neilson
Valued Contributor II
2,805 Views
Quoting - dktseng

I know because when I linked the same library in CVF, it was able to link and call those functions. I've attached the txt file.

Thanks.

In your fortran project what do you have for :
Project->Properties->Configuration Properties->Fortran->External Procedures : Calling convention ?

and do you havean "interface" block in your fortran code for the AD_S* routines ?

Les
0 Kudos
dktseng
Beginner
2,805 Views
Quoting - Les Neilson

In your fortran project what do you have for :
Project->Properties->Configuration Properties->Fortran->External Procedures : Calling convention ?

and do you havean "interface" block in your fortran code for the AD_S* routines ?

Les

Calling convention is Default.

I don't think so. What's an interface block?
0 Kudos
Les_Neilson
Valued Contributor II
2,805 Views
Quoting - dktseng

Calling convention is Default.

I don't think so. What's an interface block?


I think you should set the calling convention to STDCALL (or maybe STDCALL, REFERENCE)

An interface block is like a description, telling fortran what the routine that you are going to call looks like.

Les
0 Kudos
dktseng
Beginner
2,805 Views
Quoting - Les Neilson


I think you should set the calling convention to STDCALL (or maybe STDCALL, REFERENCE)

An interface block is like a description, telling fortran what the routine that you are going to call looks like.

Les

I tried setting the convention to STDCALL and STDCALL, REFERENCE, but no luck. It gave me the same errors plus 2 more errors.

I'm not sureif I havean interface block. But I'm running the same fortran code I ran using the CVF compilerand it ran fine.
0 Kudos
Steven_L_Intel1
Employee
2,805 Views
Quoting - dktseng

I tried setting the convention to STDCALL and STDCALL, REFERENCE, but no luck. It gave me the same errors plus 2 more errors.

I'm not sureif I havean interface block. But I'm running the same fortran code I ran using the CVF compilerand it ran fine.

When I asked how you knew you had routines _AD_SENSOR and _AD_SYSTEM in the library, you replied that it worked with CVF. Actually, you didn't know. You may have had C++ routines named AD_SENSOR and AD_SYSTEM, but, as the dumpbin shows, what you actually have in the library are routines named _AD_SENSOR@88 and _AD_SYSTEM@244 - not the same thing at all.

Intel Fortran, as is explained in the "Migrating from CVF" article, uses a different default calling convention than does CVF. Because of this, the Fortran code was looking for different symbols in the library than what were defined. The quick solution for this is to go into the project properties and set Fortran > External Procedures > Calling Convention to "CVF" and then rebuilding. Using STDCALL or STDCALL,REFERENCE is not the same thing, as that causes names to be downcased rather than upcased. I will comment that if you converted your CVF project to Intel Fortran, this setting would be applied automatically.

A better solution, in my opinion, is to remove the __stdcall that you must have in the C++ definitions of these routines. But it's your choice.
0 Kudos
dktseng
Beginner
2,805 Views

When I asked how you knew you had routines _AD_SENSOR and _AD_SYSTEM in the library, you replied that it worked with CVF. Actually, you didn't know. You may have had C++ routines named AD_SENSOR and AD_SYSTEM, but, as the dumpbin shows, what you actually have in the library are routines named _AD_SENSOR@88 and _AD_SYSTEM@244 - not the same thing at all.

Intel Fortran, as is explained in the "Migrating from CVF" article, uses a different default calling convention than does CVF. Because of this, the Fortran code was looking for different symbols in the library than what were defined. The quick solution for this is to go into the project properties and set Fortran > External Procedures > Calling Convention to "CVF" and then rebuilding. Using STDCALL or STDCALL,REFERENCE is not the same thing, as that causes names to be downcased rather than upcased. I will comment that if you converted your CVF project to Intel Fortran, this setting would be applied automatically.

A better solution, in my opinion, is to remove the __stdcall that you must have in the C++ definitions of these routines. But it's your choice.

I changed the Calling Convention to CVFdifferent errors. I've attached the log file.

_LFA_Mea_to_Lcl_delta and _LFA_Mea_to_Lcl are defined as 'extern float' arrays in the C++ program Interpolate_lfa.C.

When I remove __stdcall, I get the same errors.
0 Kudos
Steven_L_Intel1
Employee
2,805 Views

You've made progress - now you are pulling in the C++ routines. The new error is coming from the C++ code. Where are these arrays actually defined (rather than referenced as external)?
0 Kudos
dktseng
Beginner
2,754 Views

You've made progress - now you are pulling in the C++ routines. The new error is coming from the C++ code. Where are these arrays actually defined (rather than referenced as external)?

Ah, that was the problem. I didn't have those arrays defined and left it out of the C++ library. My code runs now. Now I have to see if it's giving me the right answers... fingers crossed. Thank you very much.
0 Kudos
Reply