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

Unresolved external symbols only in 64 bit

pneveu
Beginner
2,459 Views
Hi,

I'm using vc9.0 and ifort11.1 on Windows XP x64, and I'm having a 64 bit Fortran problem. I get unresolved external symbols while building a 64 bit Fortran application in 64 bit. I do not get these issues while building the same Fortran application in 32 bit.

ifort -object:C:\home\pcibin\vc9.0\cots\64BitBranch\src\pacef\debug64\ang.obj -c /nologo /W1 /iface:mixed_str_len_arg /Z7 /dbglibs -IC:\home\pciroot\64BitBranch\src\basef -IC:\home\pciroot\64BitBranch\src\pacef\NT -IC:\home\pciroot\64BitBranch\src\basef\NT "C:\home\pciroot\64BitBranch\src\pacef\ang.nt.for"
link /nologo /DEBUG /MACHINE:X64 /MANIFEST /OUT:C:\home\pcibin\vc9.0\cots\64BitBranch\src\pacef\debug64\ANG.EXE /LIBPATH:C:\home\pcibin\vc9.0\cots\64BitBranch\libdb64 pcif1040db.lib pcic1040db.lib core1040db.lib syslow1040db.lib counter1040db.lib network1040db.lib /incremental:no /subsystem:console /force:multiple /DEBUG "C:\home\pcibin\vc9.0\cots\64BitBranch\src\pacef\debug64\ang.obj"
pcif1040db.lib(impexi.obj) : warning LNK4217: locally defined symbol _exit imported in function IMPEXI
ang.obj : error LNK2019: unresolved external symbol __imp__idbiwr_ referenced in function MAIN__
ang.obj : error LNK2019: unresolved external symbol __imp__idbchw_ referenced in function MAIN__
pcif1040db.lib(impsts.obj) : error LNK2019: unresolved external symbol __imp__impfinit_ referenced in function IMPSTS
pcif1040db.lib(impsts.obj) : error LNK2019: unresolved external symbol __imp__impenv_ referenced in function IMPSTS
pcif1040db.lib(impexr.obj) : error LNK2001: unresolved external symbol __imp__dkgetw_
...
C:\home\pcibin\vc9.0\cots\64BitBranch\src\pacef\debug64\ANG.EXE : fatal error LNK1120: 19 unresolved externals



All the unresolved external symbols seems to be from C code. For some reason, it seems like it is unable to import the symbols from the pcic library. But they are there, and they are the same as in the 32 bit pcic library.

This is the import symbol in the 32 bit pcif library:

C:\tmp\bin32>dumpbin /SYMBOLS pcif1040db.lib | grep dkgetw
098 00000000 UNDEF notype External | __imp__dkgetw_

This is the import symbol in the 64 bit pcif library:

C:\tmp\bin64>dumpbin /SYMBOLS pcif1040db.lib | grep dkgetw
09C 00000000 UNDEF notype External | __imp__dkgetw_

Using depends.exe I can see that the dkgetw_ symbol is defined in pcic1040db.dll in both 64 bit and 32 bit versions.

What I'm I missing, can someone help me?

Thanks,

Phelippe

0 Kudos
1 Solution
Steven_L_Intel1
Employee
2,459 Views

I'm surprised that the symbols are the same between 32-bit and 64-bit - the 64-bit symbols should have one less leading underscore. Perhaps you can try adding /verbose to the linker options and watch how it finds things in libraries.

View solution in original post

0 Kudos
8 Replies
Steven_L_Intel1
Employee
2,460 Views

I'm surprised that the symbols are the same between 32-bit and 64-bit - the 64-bit symbols should have one less leading underscore. Perhaps you can try adding /verbose to the linker options and watch how it finds things in libraries.
0 Kudos
pneveu
Beginner
2,459 Views

I'm surprised that the symbols are the same between 32-bit and 64-bit - the 64-bit symbols should have one less leading underscore. Perhaps you can try adding /verbose to the linker options and watch how it finds things in libraries.

Well in depends.exe the symbols looks the same, but someone here gave me this info.

For the bin32 version of pcic1040db.lib...

Version : 0
Machine : 14C (x86)
TimeDateStamp: 4B156C56 Tue Dec 01 14:19:50 2009
SizeOfData : 00000018
DLL name : pcic1040db.dll
Symbol name : _dkgetw_
Type : code
Name type : no prefix
Hint : 13052
Name : dkgetw_

Archive member name at 45AF40: pcic1040db.dll/
4B156C56 time/date Tue Dec 01 14:19:50 2009
uid
gid
0 mode
2D size
correct header end

For the bin64 version of pcic1040db.lib...

Version : 0
Machine : 8664 (x64)
TimeDateStamp: 4B15F978 Wed Dec 02 00:22:00 2009
SizeOfData : 00000017
DLL name : pcic1040db.dll
Symbol name : dkgetw_
Type : code
Name type : name
Hint : 13052
Name : dkgetw_

Archive member name at 476282: pcic1040db.dll/
4B15F978 time/date Wed Dec 02 00:22:00 2009
uid
gid
0 mode
2C size
correct header end


So the 64 bit version does have one less _ in front of the symbol. So to make this work for both 32 bit and 64 bit, the only solution I have is too export the symbols differently in 64 bit? So I should export "_dkgetw_" in 64 bit and "dkgetw_" in 32 bit. I guess this is only valid for VC since we don't seem to have this problem using gcc and gfortran.

Thanks for your help,

Phelippe

0 Kudos
Steven_L_Intel1
Employee
2,459 Views

Are you using gcc and gfortran on Windows? The difference in the underscore is Microsoft's published convention. If gcc and gfortran on Windows aren't obeying that, they're in error.

Don't use depends - it is not reliable for this. Use "dumpbin -exports" on the export library instead.
0 Kudos
TimP
Honored Contributor III
2,459 Views
Lower case with appended underscore (same as linux) is normal for certain versions of gcc and gfortran. It's practically impossible to make gfortran and ifort objects work together anyway, and certainly not something which will "just work" between gcc and ifort Windows, as it would on linux. You would never be able to link 64- and 32-bit objects together, regardless of symbol case and underscoring or which compilers are involved.
0 Kudos
pneveu
Beginner
2,459 Views

Are you using gcc and gfortran on Windows? The difference in the underscore is Microsoft's published convention. If gcc and gfortran on Windows aren't obeying that, they're in error.

Don't use depends - it is not reliable for this. Use "dumpbin -exports" on the export library instead.

Sorry for my late reply, I was on vacation. I will clarify my initial problem. We have multiplatform code that we compile on Linux and Windows. On Linux we use gcc and gfortran, on Windows we use VC++ and Ifort. We recently ported our code to 64 bit. So I needed a way to compile the same code on Linux and Windows in 32 and 64 bit. We used to support alot more platforms and we had defines to properly export the symbols so that they are the same on all platforms.

#ifdef forname_
# define DKGETW dkgetw_
#endif

#ifdef forname
# define DKGETW dkgetw
#endif

void DKGETW(...)
{
}

So I fixed my problem by adding a new define called _forname_ which is defined on Windows platform when compiling in 64 bit. Then I added the following block:

#ifdef _forname_
# define DKGETW _dkgetw_
#endif

I had to do this for all C symbols we were importing. It is not a trivial change, but it is the only way I found without changing our Fortran code.

Phelippe
0 Kudos
Steven_L_Intel1
Employee
2,459 Views

I don't quite understand - on 64-bit Windows, there would be neither a leading nor a trailing underscore in the external name.
0 Kudos
pneveu
Beginner
2,459 Views

I don't quite understand - on 64-bit Windows, there would be neither a leading nor a trailing underscore in the external name.

We do this so that the symbols exported are all identical for all platform/ABI combinations we compile on. If we do not do this, the symbol exported on Windows 64 bit would be dkgetw, on Windows 32 bit would be _dkgetw and on Linux 64 and 32 bit would be _dkgetw. So it means we would need to import the symbols differently when compiling on Windows in 64 bit. I think the trailing _ was added for other platforms we no longer support, so it is irrelevant.

This is how we import the symbols in Fortran:

SUBROUTINE DKGETW (unit,jstrbk,numblk,buffer)
INTEGER unit
INTEGER jstrbk
INTEGER numblk
INTEGER buffer(*)
cDEC$ ATTRIBUTES DLLIMPORT :: DKGETW
cDEC$ ATTRIBUTES C, ALIAS:'_dkgetw_' ::DKGETW
cDEC$ ATTRIBUTES REFERENCE :: unit, jstrbk, numblk
cDEC$ ATTRIBUTES NO_ARG_CHECK::buffer
END SUBROUTINE DKGETW

Hope it clarifies things if ever someone else runs into the same problem. I don't have any experience in Fortran, so I'm not sure if there is an easier way to do this.

Phelippe

0 Kudos
Steven_L_Intel1
Employee
2,459 Views

Well, this is why I suggested using BIND(C) - or perhaps DECORATE along with ALIAS. You would no longer have to worry about underscores - the compiler would "do the right thing" for the given platform.
0 Kudos
Reply