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

Linker error following move to 64bit with ifx

SoniaG
Novice
1,010 Views
Hello,
I am converting a very large 32 bit application to 64 bit for use with the ifx compiler and am getting linker errors relating to the C code (which is running error free in 32bit with ifort).
 
The application has 5 calls to C routines (all now failing to link) but to keep things simple I have only included details of one of them (c_get_tiff_size) below:
 
Declared in the Fortan subroutine as:
interface
   logical*4 function c_get_tiff_size(fullname,nrows,ncols)
      use, intrinsic :: iso_c_binding
      !DEC$ ATTRIBUTES C :: c_get_tiff_size
      character(*) fullname
      integer*4 nrows,ncols
      !DEC$ ATTRIBUTES REFERENCE :: fullname,nrows,ncols
      end function c_get_tiff_size
end interface
 
C routine (c_get_tiff_size) in the .cpp file (compiled with Intel C++ 2024 in a static lib):
 
extern "C" { int c_get_tiff_size(char* fullname, uint32* ncols, uint32* nrows)
{
TIFF* tif;
int OK = FALSE;
 
//Open tiff file for reading
tif = TIFFOpen(fullname, "r");
if (tif) {
  //Get image width (number of columns).
  if (TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, ncols) != 0)
  {
//Get image height (number of rows).
if (TIFFGetField(tif, TIFFTAG_IMAGELENGTH, nrows) != 0)
OK = TRUE;
  }
  TIFFClose(tif);
}
return(OK);
}}
 
Linker error:
1>------ Build started: Project: FMIS (IFX), Configuration: Debug x64 ------
Compiling with Intel® Fortran Compiler 2024.1.0 [Intel(R) 64]...
AnaImage.f90
Linking...
AnaImage.obj : error LNK2001: unresolved external symbol c_get_tiff_size
 
Things I have tried (without success)..
Within the declaration in the fortran subroutine, changed the
"!DEC$ ATTRIBUTES C :: c_get_tiff_size" to:
 
!DEC$ ATTRIBUTES C, ALIAS: 'c_get_tiff_size'
 
and also tried:
!DEC$ ATTRIBUTES C, decorate, ALIAS: 'c_get_tiff_size'
 
I also added  to logical*4 function c_get_tiff_size(fullname,nrows,ncols) bind(C, name = "c_get_tiff_size")
 
Dumpbins for the fortran obj file and .cpp obj file show:
 
dumpbin -symbols anaImage.obj
217 00000000 UNDEF  notype       External     | c_get_tiff_size
 
dumpbin -symbols ReadTiff.obj
042 00000000 SECT8  notype ()    External     | c_get_tiff_size
 
The c code in our Fortran application has been untouched and built perfectly for many years. I assume it must be a 64bit issue (possibly clouded by the simultaneous move to the ifx compiler) but I am unsure of what to try next and hoping someone can help me please. 
 
Another thought I had was that the fortran code can't read the .lib produced in the C project but I'm not sure how to check this.
 
Many thanks in advance,
Sonia
0 Kudos
14 Replies
Arjen_Markus
Honored Contributor I
1,002 Views

I think you should rely on the ISO C binding and not on the ATTRIBUTES compiler directives. First of all, because the directives are not part of the Fortran standard, but more importantly because the combination might cause confusion.

Judging from the description you gave it could be something like (untested):

logical*4 function c_get_tiff_size( fullname, nrows, ncols ) bind(C, name="c_get_tiff_size")
    character(len=1) :: fullname(*)
    integer :: nrows, ncols
end function c_get_tiff_size

 Notes:

  • logical*4 and integer*4 are extensions
  • the string fullname should be ending in a char(0) at the caller's side
  • strings are passed as if they are character(len=1) arrays instead of strings.
0 Kudos
SoniaG
Novice
877 Views

Thanks for the quick response  @Arjen_Markus. I have tried the adjusted interface with no luck I'm afraid. Any other ideas happily received though!

0 Kudos
Ron_Green
Moderator
930 Views

Did you rebuild the C library as an x64 application?  if not, you are probably correct that the 32bit .lib will not work with a x64 Fortran object or library.

0 Kudos
SoniaG
Novice
877 Views

Thanks @Ron_Green  for your reply. Yes I built the C lib in 64bit. Anything else I can try/test?

0 Kudos
mecej4
Honored Contributor III
840 Views

The external symbol c_get_tiff_size is available in the object file ReadTiff.obj. Therefore, check in your project settings and check the linker command to see if ReadTiff.obj is being included in the list of files to be linked. I do not see more than just one mention of ReadTiff.obj in your post, which raises my suspicion that the linker command is perhaps in need of correction.

0 Kudos
SoniaG
Novice
748 Views

Thanks for your input @mecej4 .

The library containing c_get_tiff_size.obj is called FMIS.lib and I have placed a copy of the release version in the folder of the main project (called FMIS) and my linker settings for the main project are as follows (Visual Studio 2019) :

SoniaG_0-1716771960651.png

SoniaG_1-1716771987416.png

I am not that familiar with linker settings so maybe I may have made an error somewhere? I added the full path for the FMIS-C library in the Fortran settings but not sure if it is required (but seems to make no difference).

SoniaG_2-1716772425590.png

 

Thanks, Sonia

0 Kudos
jimdempseyatthecove
Honored Contributor III
544 Views

>>The library containing c_get_tiff_size.obj is called FMIS.lib and I have placed a copy of the release version in the folder of the main project

 

Did you move the 32-bit or 64-bit .obj?

And, if that is referencing a .dll, did you also move the .dll into the folder where the .exe was built? (or current directory of debug session).

 

Jim Dempsey

0 Kudos
SoniaG
Novice
505 Views

Hi @jimdempseyatthecove , thanks for your input.

I just attempted to build the project with the x64\Debug folder containing: 

the release version .obj files from the FMIS-C project,

the release version FMIS-C.lib,

the 4 x DLLs that the FMIS-C project references.

Unfortunately I am still getting the same errors. Presumably if there was a problem with the DLLs it would have appeared when I built the FMIS-C project.

I am running out of ideas...

 

 

0 Kudos
andrew_4619
Honored Contributor III
685 Views

linker > general > show progress   (/verbose) show a listing of what the linker is doing. That should illuminate matters.

SoniaG
Novice
570 Views

Thanks @andrew_4619 .

The additional output I received from changing the linker setting is telling me that the linker can find the the c routines, and 'references' them but does not load the FMIS-C library as it does for odbc.lib which follows it.

Any ideas on where this should point me?

SoniaG_0-1716954449688.png

Many thanks.

 

0 Kudos
andrew_4619
Honored Contributor III
473 Views

Your interface is questionable, for example on the C side nrows and ncols are pointers so it is expecting a memory address to be passed by value. 

0 Kudos
SoniaG
Novice
405 Views

@andrew_4619  I tried passing in loc(nrows) and loc(ncols) values etc but the error remained.

The error is received on all of the C routines (all have various items passed in - not all pointers) so I think my error is a broadscale one. The fact that all of my C code runs error free in 32bit also indicates that it is something generic to all of the c code.

SoniaG_0-1717144319705.png

 

 

0 Kudos
andrew_4619
Honored Contributor III
386 Views

I am not the person to help with this my knowledge and usage of C is minimal. However create a new simple routine in your c file e with a void function that passes nothing, interface and call it on the Fortran side and see if that links....  

0 Kudos
SoniaG
Novice
211 Views

Thanks for the suggestion @andrew_4619 .

I added a simple void function that takes no parameters, and referenced it in my Fortran code. It's name (myVoidFunction) now appears in the Linker's error list along with all of the original C routines :

SoniaG_0-1717477128725.png

This seems to indicate that the issue is affecting all C code, regardless of referencing style or parameters being passed in or not (unless something else could be "muddying the waters")? 

I will perhaps try creating a whole new C project with only the void function and see where that takes me as i seem to be running out of options

0 Kudos
Reply