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

MS VC DLL linking with IVF static library

jimdempseyatthecove
Honored Contributor III
4,072 Views

I have some unresolved symbol issues. First background

Solution has a C# project that uses an MS VC++ .DLL also in the solution, the DLL in turn links with an IVF static library. I am receiving linking errors when linking the .DLL. I have resolved most of the unresolved symbols excepting for:

error LNK2001: unresolved external symbol for_check_mult_overflow64
error LNK2001: unresolved external symbol for_alloc_allocatable
error LNK2001: unresolved external symbol for_dealloc_allocatable
error LNK2001: unresolved external symbol for_stop_core
error LNK2019: unresolved external symbol for_cpystr
error LNK2019: unresolved external symbol d_int_val
error LNK2019: unresolved external symbol for_fp_class_s_
error LNK2019: unresolved external symbol for_fp_class_t_
error LNK2019: unresolved external symbol for_fp_class_x_
error LNK2019: unresolved external symbol for_is_nan_s_
error LNK2019: unresolved external symbol __for_ieee_set_flag_
error LNK2019: unresolved external symbol for_is_nan_t_
error LNK2019: unresolved external symbol for_is_nan_x_
error LNK2019: unresolved external symbol for_get_fpe_
error LNK2019: unresolved external symbol for_exponent4_v
error LNK2019: unresolved external symbol for_exponent8_v
error LNK2019: unresolved external symbol for_exponent16_v
error LNK2019: unresolved external symbol __for_ieee_next_after_k4_8
error LNK2019: unresolved external symbol __for_ieee_next_after_k8_
error LNK2019: unresolved external symbol __for_ieee_next_after_k16_
error LNK2019: unresolved external symbol __for_ieee_rem_k8_
error LNK2019: unresolved external symbol __for_ieee_rem_k16_
error LNK2019: unresolved external symbol __for_ieee_scalb_k44_
error LNK2019: unresolved external symbol __for_ieee_scalb_k84_
error LNK2019: unresolved external symbol __for_ieee_scalb_k164_
error LNK2019: unresolved external symbol for_set_fpe_
error LNK2019: unresolved external symbol __for_ieee_get_flag_
error LNK2019: unresolved external symbol __for_ieee_set_halting_mode_
error LNK2019: unresolved external symbol __for_ieee_get_halting_mode_ 

The solution also contains and IVF test program that links with the IFV static library. The test program links and runs properly.

Compiling the C++ project with Intel C++ has issues with namespace System.

I haven't tried making my Fortran static library into a .DLL. I though I'd ask before going that route.

Jim Dempsey

0 Kudos
29 Replies
mecej4
Honored Contributor III
2,792 Views

Jim, I think that the unresolved externals will be resolved if the link is done with ifort (rather than cl or icl). If there is a good reason for not wanting to use ifort to do the linking, the Fortran runtime libraries will need to be added to the linker command (or specified using the LINK environment variable). What you saw is usually the result of using a library that was previously built from Fortran sources with new code that is compiled and linked with C or C# compilers.

0 Kudos
Steven_L_Intel1
Employee
2,792 Views

First, read: How do I configure Microsoft Visual C++ for developing mixed Fortran-C applications?

You also need to make sure that your static library project has the property Fortran > Libraries > Disable OBJCOMMENT set to No (this is the default.)

Is this an x64 configuration?

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,792 Views

How do I do this from VS 2013? (how do I specify to use ifort in the link of a VS C++ Project?)

Jim Dempsey

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,792 Views

Yes, this is x64. Disable OBJCOMMENT is set to No

Will read your link.

Thanks

Jim Dempsey

0 Kudos
Steven_L_Intel1
Employee
2,792 Views

I wonder if you have the path to the IA-32 libraries being used for your x64 project. Otherwise I would have expected error messages about libraries not found. Setting the Linker property "Show progress messages" to "Show some progress messages" will tell you the paths to the libraries it searched.

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,792 Views

Thanks for the additional, and helpful hints at tracking down the issue. I will try the info in the link you provided in #3 first, then use the show progress messages if I continue to have problems.

Not that this matters (I don't think it is relevant), the C++ project in the solution, used as an interface between the C# portion and the Fortran portion, was originally built using MS VC++. In trying to resolve the issue, I set the project properties to use Intel C++ (version 15.0, update 4). That produced a whole slew of other errors (in particular missing namespace System). Therefore I set the Project back to use MC VC++. After setting it back, the title line of the project reads

>[++] myProject (Intel C++ 15.0)

but all the property pages read MS VC++

You might inform the integration people about this.

I will know later on this morning as to if I have the undefined linker entry points resolved.

Thanks again, see you at IDF (assuming you go)

Jim Dempsey

0 Kudos
Steven_L_Intel1
Employee
2,792 Views

You may want to report the project issue (and the build issue) in the Intel C++ forum.

As for IDF, it's unknown at this time if I'll be there this year, but if I am I will be glad to see you again.

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,792 Views

Well this is interesting...

Navigating to Command Prompt for PS 2015 Intel 64 VS 2013

And issuing SET to see the environment variables,

I do not see IFORT_COMPILER15

I do see:

...
IFORT_COMPILER12=C:\Program Files (x86)\Intel\Composer XE 2011 SP1\
IFORT_COMPILER14=C:\Program Files (x86)\Intel\Composer XE 2013 SP1\
include=C:\Program Files (x86)\Intel\Composer XE 2015\ipp\include;
  C:\Program Files (x86)\Intel\Composer XE 2015\mkl\include;
  C:\Program Files (x86)\Intel\Composer XE 2015\tbb\bin\..\include;
  C:\Program Files (x86)\Intel\Trace Analyzer and Collector\9.0.2.045\include
INSPECTOR_2015_DIR=C:\Program Files (x86)\Intel\Inspector XE 2015\
...

Note 14 has a blend of 14 and 15 paths???

Also, from that command prompt launched from:

Start | All Programs | Intel Parallel Studio XE 2015 | Compiler and Performance Libraries | Command Prompt wit Intel Compilers | Intel 64 Visual Studio 2013 mode

Issuing:

ifort -h

yields: 'ifort' is not recognized as an internal or external command

 

PATH=C:\Program Files (x86)\Intel\Composer XE 2015\ipp\..\redist\ia32\ipp;
  C:\Program Files (x86)\Intel\Composer XE 2015\ipp\..\redist\ia32\compiler;
  C:\Program Files (x86)\Intel\Composer XE 2015\redist\ia32\mkl;
  C:\Program Files (x86)\Intel\Composer XE 2015\redist\ia32\compiler;
  C:\Program Files (x86)\Intel\Composer XE 2015\tbb\bin\..\..\redist\ia32\tbb\vc12;
  C:\Program Files (x86)\Intel\Advisor XE 2015\.\bin32;
  C:\Program Files (x86)\Intel\Inspector XE 2015\bin32;
  C:\Program Files (x86)\Intel\Trace Analyzer and Collector\9.0.2.045\dll

I do not see:

C:\Program Files (x86)\Intel\Composer XE 2015\bin\intel64

where ifort and icl live.

Additionally, from the prompt launched from the Start | ...

C:\Program Files (x86)\Intel\Composer XE 2015>cd bin
C:\Program Files (x86)\Intel\Composer XE 2015\bin>compilervars intel64
ERROR: Visual Studio 2010, 2012 or 11 is not found in the system.

C:\Program Files (x86)\Intel\Composer XE 2015\bin>compilervars intel64 vs2013
ERROR: Visual Studio 2013 is not found in the system.

C:\Program Files (x86)\Intel\Composer XE 2015\bin>compilervars intel64 vs2012
ERROR: Visual Studio 2012 is not found in the system.

Issuing:

C:\Program Files (x86)\Intel\Composer XE 2015\bin>intel64\ifort
Intel(R) Visual Fortran Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 15.0 Build 20150407

Integration into VS 2013 is working fine, within the environs of IVF or ICC or MS C++, with minor issue of .AND.

I will experiment with the path settings, if problems continue, I will reinstall PS 2015 and updates. (takes a while to do this)

Jim Dempsey

 

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,792 Views

Just noticed,

The Intel64 command prompt launch, path settings not only is missing the path to the ...bin\intel64 folder but the other paths point to the ia32 sub folders.

Jim Dempsey

0 Kudos
Steven_L_Intel1
Employee
2,792 Views

Looks to me as if the 2015 Fortran is not installed, though the performance libraries that come with Intel C++ are. I suggest you rerun the 2015 install, do a "Change or Modify" and note carefully any error messages or what shows on the component selection screen. I don't see a "blend of 14 and 15" in the definition of IFORT_COMPILER14.

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,792 Views

Installing 2015 update 4 for Fortran
(o) Modify
IA-32
Intel(R) 64
Math Kernel Library has components unchecked that I don't need (Cluster, PGI, SP2DP)
   Left those unchecked
Intel Debugger Extension has components unchecked that I don't need (GNU* GDB Sources)
   Left those unchecked
MS VS 2010
[  ] MS VS 2012 (greyed out)
MS VS 2013
[  ] MS VS 2015 (greyed out)

Upon Next, I get "Nothing to modify" in the installation summary

Using "Prev" button I go back to

(o) Repair

Upon Next, I get "Repair can't be done because no available sources were found."

I think I will hand construct the IFORT_COMPILER15 environment variable, and fix PATH, but this won't likely get compilervars.bat working.

While I could uninstall each of the PS 2015 components in reverse order, reboot, reinstall PS 2015 (base level), then update 4's (C and F), I must note that the base level of PS XE 2015 did not integrate well into MS VS 2013, whereas update 4 of C and F did afterwards.

Doing the above steps will likely consume a day, and end up where I am at.

Could you (or someone on this forum with MS VS 2013 installed) perform a

Start | CMD  (launch the default command prompt)

SET > DefaultSET.txt

and perform

Start | All Programs | Intel Parallel Studio XE 2015 | Compiler and Performance Libraries | Command Prompt wit Intel Compilers | Intel 64 Visual Studio 2013 mode

(launch the Intel 64 PS 2015 XE command prompt)

SET > Intel64SET.txt

Then attach the two .txt files to your Reply. I think I can sort out the settings a little easier.

Jim Dempsey

0 Kudos
Steven_L_Intel1
Employee
2,792 Views

Here's what I have, but note that I choose to install each update separately so I have the specific versions listed. (I have not installed Update 4 on this system yet):

C:\Users\sblionel>set ifort
IFORT_COMPILER12=C:\Program Files (x86)\Intel\Composer XE 2011 SP1\
IFORT_COMPILER13=C:\Program Files (x86)\Intel\Composer XE 2013\
IFORT_COMPILER14=C:\Program Files (x86)\Intel\Composer XE 2013 SP1.237\
IFORT_COMPILER15=C:\Program Files (x86)\Intel\Composer XE 2015.3.208\

With the shortcut, my PATH starts out like this:

Path=C:\Program Files (x86)\Intel\Composer XE 2015.3.208\bin\intel64;C:\Program
Files (x86)\Intel\Composer XE 2015.3.208\redist\intel64\compiler;C:\Program File
s (x86)\Microsoft Visual Studio 12.0\Common7\IDE\CommonExtensions\Microsoft\Test
Window;C:\Program Files (x86)\Microsoft SDKs\F#\3.1\Framework\v4.0\;C:\Program F
iles (x86)\MSBuild\12.0\bin;C:\Program Files (x86)\MSBuild\12.0\bin;C:\Program F
iles (x86)\Microsoft Visual Studio 12.0\Common7\IDE\;C:\Program Files (x86)\Micr
osoft Visual Studio 12.0\VC\BIN\x86_amd64;C:\Program Files (x86)\Microsoft Visua
l Studio 12.0\VC\BIN;C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7
\Tools;C:\windows\Microsoft.NET\Framework\v4.0.30319;C:\Program Files (x86)\Micr
osoft Visual Studio 12.0\VC\VCPackages

I don't see mention of the compiler in your interpretation of the component selection screen. Maybe you should try an uninstall and reinstall.

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,792 Views

Thanks again....

Before I progress....

After getting the "Nothing to do" on both the modify and refresh, MS VS 2013 would fail to launch (reported this earlier), the devenv.exe fix to reset the settings didn't work, but a reboot of the system worked to restore MS VS 2013.

(Set aside the following relating to C++ as opposed to Fortran, the environments are related...)

I made simple Hello World C++ solution/project to print text and the address of the text pointer MS VC++ Win32 and x64 worked as expected (different size pointer). I set the project to use Intel C++

The Platform pull-down was set to x64. I wanted to do the Win32 test first, so I pulled down the Platform and selected Win32. Win32 displayed. I performed the ReBuild and ran... but the pointer size displayed 64-bit pointer. Pulling down the Platform pull-down again (was still in Win32), selecting Configuration Manager, The Win32 platform still showed x64. This flummox in the IDE integration may be a key to why it may appear that the Linking of the 64-bit DLL with my 64-bit static Library seemed to be searching the 32-bit library path. (this is all supposition by the way).

Any-who

Back to the path issue.

After performing the reboot, following the "Nothing to do", and the reboot, followed by the peculiar Platform flummox, I went to the Control Panel | System Properties | Environment Variables...

And, guess what? System variables now contains

IFORT_COMPILER15=C:\Program Files (x86)\Intel\Composer XE 2015\

Apparently the "Nothing to do" did something, or the Repair "No sources" did something.

This odd behavior to say the least.

From the position I am in now, I will go back to your post #3 link, then work with other environment variables if necessary from reply #13.

Jim Dempsey

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,792 Views

Success!!!

At least the C++ DLL links now. The C# program is having an issue, but that is a subject for a different forum...

Jim Dempsey

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,792 Views

And the saga continues...

I do have something a bit different to ask of you today. Yesterday everything was going fine I could build the 64-bit solution fine. one of the C# programs was missing a component, so I set back to 32-bit platform, and performed a build. This worked, and I thought everything was fine. I exited VS, two instances running, one with the newer solution, and one with the older solution, both using different folder paths. However, it should be noted that the affected project has the same project name in both solution paths (different file folders, same project name, different solution name).

This morning I come in, and I am getting build errors in the link phase of the MS C++ interface file (.DLL) between the C# code and the Fortran .lib file:

Pavement.obj : error LNK2028: unresolved token (0A000202) "extern "C" void __stdcall crames_input(int,int,int,int,double *,double *,double *,int *,double *,double *,double *,int,int,int,double *)" (?crames_input@@$$J260YGXHHHHPAN00PAH000HHH0@Z) referenced in function "public: void __thiscall Pavement::Calculate(int,int,int,bool,int)" (?Calculate@Pavement@@$$FQAEXHHH_NH@Z)
Pavement.obj : error LNK2019: unresolved external symbol "extern "C" void __stdcall crames_input(int,int,int,int,double *,double *,double *,int *,double *,double *,double *,int,int,int,double *)" (?crames_input@@$$J260YGXHHHHPAN00PAH000HHH0@Z) referenced in function "public: void __thiscall Pavement::Calculate(int,int,int,bool,int)" (?Calculate@Pavement@@$$FQAEXHHH_NH@Z)


This occurs in the build (Link) of the .dll. As I said this was working yesterday, and other than saving the two instances of VS I did nothing source code for the .dll nor the .lib (but they did rebuild). Only the newer solution is open.

In exploring the problem, I used dumpbin and find in the.obj file loaded into the .lib:

00A 00000000 SECT3  notype       Static       | _crames_input$BLK..T567_
...
021 00000000 SECT5  notype       Static       | _crames_input$EIGEN_VEC
022 00000180 SECT5  notype       Static       | _crames_input$EIGEN_VAL

but I do not find the decorated names.

Performing the dumbbin on the .dll source shows the decorated name:

7A4 00000000 UNDEF  notype ()    External     | ?crames_input@@$$J260YGXHHHHPAN00PAH000HHH0@Z (extern "C" void __stdcall crames_input(int,int,int,int,double *,double *,double *,int *,double *,double *,double *,int,int,int,double *))

The .F90 source file that contains the subroutine was untouched:

SUBROUTINE crames_input(nlays1,nlds_rect1,nlds_circ1,nmp1,layerarr,loadarr1,loadarr2, &
    npointsarr,pointsarr,resultsarr,principalarr,iOption1,iAccuracy1,iSlip1,sedarr)

!DEC$ ATTRIBUTES STDCALL, ALIAS: 'crames_input' ::  crames_input
!DEC$ ATTRIBUTES REFERENCE::layerarr,loadarr1,loadarr2
!DEC$ ATTRIBUTES REFERENCE::npointsarr,pointsarr,resultsarr
!DEC$ ATTRIBUTES REFERENCE::principalarr
!DEC$ ATTRIBUTES REFERENCE::sedarr
!!DEC$ ATTRIBUTES VALUE::nlays1,nlds_rect1,nlds_circ1,nmp1,iOption1,iAccuracy1,iSlip1

Note the !! on the value, not required for stdcall, and won't explain missing decorations.

Jim Dempsey

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,792 Views

Additional information reguarding the build of the static library:

ifort /nologo /debug:full /Od /module:"Debug\\" /object:"Debug\\" /Fd"Debug\vc120.pdb"
 /traceback /check:bounds /check:stack /libs:dll /threads /dbglibs /c /Qvc12
 /Qlocation,link,"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\\bin"
 "{source files here}"
Creating library...
Lib /OUT:"Debug\myLibHere.lib" /NOLOGO {objFilesHere}
xilib: executing 'lib'
 

Jim Dempsey

0 Kudos
Steven_L_Intel1
Employee
2,792 Views

Odd that you seem to have 'extern "C"' yet it name-mangled the routine name. This is a C++ issue, not Fortran.

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,792 Views

Thanks, I've been focusing on the Fortran side. I will look at the extern "C" side in the C++ .dll solution.

On a related subject, if I were to change the .f90 code to use BIND(C) and ISO_C_BINDING, would this generate the decorated names?

Jim Dempsey

0 Kudos
Steven_L_Intel1
Employee
2,792 Views

No. Fortran knows nothing about C++ or how it decorates names.

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,680 Views

As a means to diagnose this problem, I added to the C++ file and to a .f90 file in the Fortran project

// in .cpp file
extern "C" {
 void __stdcall FooBar();
}

! in .f90 file, ** note explicit decoration of name
SUBROUTINE FooBar()
!DEC$ ATTRIBUTES STDCALL, ALIAS: '?FooBar@@$$J10YGXXZ' ::  FooBar
  Write(*,*) "remove this subroutine"
end SUBROUTINE FooBar

Linking errors out with:

LINK : error LNK2034: metadata inconsistent with COFF symbol table: symbol '?FooBar@@$$J10YGXXZ' (00000000) has inconsistent metadata with (0A000145) in Pavement.obj
Pavement.obj : error LNK2020: unresolved token (0A000145) "extern "C" void __stdcall FooBar(void)" (?FooBar@@$$J10YGXXZ)
 

Using the undecorated name in the ALIAS produces the symbol not found.

Why the mixup in the metadata between IFORT and MSVC?

Jim Dempsey

0 Kudos
Reply