[SOLVED] Unresolved external symbol with erroneous parameter byte indicator...

[SOLVED] Unresolved external symbol with erroneous parameter byte indicator...

Greetings all,After four days' effort I am at wits' end. My problem concerns the linker reporting an unresolved external symbol indicating a different number of bytes in the parameter indicator e.g. _GEODW1@28 where the include file definition is _GEODW1@24, which corresponds to the parameter variables and their declaration in my calling routines. At first I thought I had a problem with my code or at the very least a problem with the settings in my project noting that the dll that contains these external symbols are in an old CVF dll. The strange thing is that I have other routines in the same project with exactly the same declaration of variables and call the same external routines and the linker never complains in their cases. Sometimes, after cleaning the project and rebuilding the solution more such errors will appear and after cleaning the project again they will disappear again seemingly in a random fashion wihtout any change in the code or in the project settings. In an effort to prove a point I gave my code to a colleague that has the same compiler. He confirmed that he was able to compile the code and link it without any changes needed to the code. So the answer was that I obviously must have an error in my project settings, but after having compared each setting in the entire project with those of my colleague I can confirm that they are identical. The only remaining difference is that he is on Windows XP SP3 and I am on Windows 7 32 bit. As far as the rest of the information is concerned:Compiler:Intel Fortran professional Edition 11.1.065 update 6 updated withIntel Fortran professional Edition 11.1.070 update 8MS Visual Studio 2008 SP1I could provide snippets of my code, but that would seem to cloud the issue as my colleague was able to compile and link the code on his setup without any change to the code. The question is what gives?!?!? I have even resolved to uninstall and reinstall everything, this time making sure I install just the minimum so as to illiminate any other external factors. Can anybody kindly please think of anything else I can try besides jumping from the top floor of our building? Yes, I am becoming that frustrated with this error!l8r

14 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.
bmchenry's picture

Speculating on your situation, i would say you may have some 'garbage' in your build or include directories...meaning perhaps older version of objects or interfaces which are picked up by the linker before the correct one so they generate issues.
Or older versions that are not deleted when you 'clean' the solution becuase you renamed a routine and the old object/interface is still there.
(Clean only cleans what is in your project and as Steve has said, to do otherwise could reap havoc if it deletes everything in a directory)
SO
check your include directories and be sure they are 'clean' of older versions of your routines
what happens, particulalry when you're changing build and include directories to solve the issue.

Thanks for your reply. I should have mentioned that one of the steps that I have taken was not to trust the clean project item on the menu, but to actually go to the build directories/space and manually deleting all previously built/compiled files between different compilation efforts. Also note that this project was not migrated from CVF, which resides on another PC. Only the source files, the CVF dll, its lib and include file that defines the interfaces of the CVF dll were copied over to the new Windows 7 PC.With high respect to Steve and his valued advice, I am not sure that deleting everything manually in my case would have made any difference. Anyway, I have just done so again and now two more spurious unresolved errors have appreared. I have even restarted the project completely new, i.e. deleting the whole directory and starting fresh just with the source files and the CVF dll, lib and include file in a completely new project. This still made no difference.I do not quite understand to what you refer when you say I could have "older versions of object files/interfaces". If I have deleted them all except the one's that I need and that are not rebuilt or edited in any way, then there cannot be such older files. Also, once the wrong file is picked up, surely it would generate an error for each case where the particular routine is called and not just in one or two places.Do not take my tone as not appreciating your reply, I really am glad that someone else is willing to spend a few moments on proposing something else that I should check, so thanks again!

bmchenry's picture

guess i'll jump in one more time..
what is the calling arguments of _GEODW1@28 (also known as_GEODW1@24)
i'm guessing there is a character variable in there?
one other item of difference since you are using a CVF dll is the calling type.
Fortran->External Procedures->Callin Conventions
I am guessing both you and the 'other' system have 'Default'.
AHA! pehaps the default is different on each system?
4 types of calls, C,REF, Std Call, Ref, Std call, and CVF
the 'clean' system may default to a different default than your system

the reason i say character is that may add/subtract bytes based on calling convention.

give it a whirl.
One last recommendation: Why don't you move the CVF code for the DLL to IVF and rid yourself of the compatibility issues?
I would guess it's code written by another?
anyhow, good luck!

Thanks again for this reply.You guesed correctly and incorrectly. Yes, the parameters for the GEODW1 routine does contain a character string. Unfortunately, because this is a CVF dll both projects on both machines have the calling convention set to CVF and the character string length indicator set to be directly following the string. These are specific setting no defaults. But you gave me an idea, maybe there are some other settings that would seem innocent and were set to default, but that have different meanings as far as default is concerned.I would desperately like to move the CVF to IVF (yes, it is code written by another and dates back many years), but there are litterally thousands of users using this dll and they would not be keen to change all their programs just because we chose to move from CVF (my version dates from 1996!) to IVF. In fact we have a version compiled with IVF, but it is no use getting that to work if I cannot use it in practice so I have not even tried. I do not even know where that version is because I would not like to add another variable factor to my strange behaviour. As I said, I have several different routines in the same project and in different source files, have the same identical declarations of parameter variables and in all of these routines the linker does not complain about this issue, but only in one of these subourtines. If I had the error consistantly everywhere I could understand it, but the fact that it gives it in only one routine and the same code links with no error on another PC makes me feel confident that the problem does not occur due to the code or the dll, but either due to some settings (compared and I still am of the opinion that they are the same with the exception of what default could mean in some cases) or the actual configuration on my PC. I was wondering whether there is no a difference in the linker that we both use and was thinking of trying to invoke the linking from the commandline to see what this reports.

Wendy Doerner (Intel)'s picture

If you have a test case you can zip up and attach to this issue we can take a look.

------

Wendy

Attaching or including files in a post

Thanks finally to Wendy and bmchenry for your comments and willingness to help. Some clues came to light when we realised that another difference between the case where the program linked and did not link was MS VS 2005 (linked) and MS VS 2008 (did not link). This caused us to look more closely at the include file that defines the interfaces to the routines in the CVF dll. The original definition of the interface was: INTERFACE TO SUBROUTINE GEODW1 (RLONG,RLAT,RANGE,CTY,XDST,XAZI)!MS$ ATTRIBUTES DLLEXPORT :: GEODW1!MS$ ATTRIBUTES STDCALL, REFERENCE, ALIAS: '_GEODW1@24' :: GEODW1!MS$ ATTRIBUTES REFERENCE :: CTY REAL*4 RLONG, RLAT, RANGE, XDST, XAZI CHARACTER*3 CTY ENDThis resulted in the code not linking with the incorrect reporting of the parameter list byte length. If this code is replaced with:$if .not. defined (GEODW1) INTERFACE TO SUBROUTINE GEODW1 (RLONG,RLAT,RANGE,CTY,XDST,XAZI)!DEC$ ATTRIBUTES DLLEXPORT :: GEODW1!DEC$ ATTRIBUTES STDCALL, REFERENCE, ALIAS: '_GEODW1@24' :: GEODW1!DEC$ ATTRIBUTES REFERENCE :: CTY REAL*4 RLONG, RLAT, RANGE, XDST, XAZI CHARACTER*3 CTY END$endifThe code links (without change anything in the rest of the code or any other setting in the project) and seems to run correctly (this include file is an even older version since it was used for the DEC Fortran compiler). Seems, because I have not yet had the time to test the results in detail.Having accepted that this code solves the linking problem, I was wondering why. And in particular why MS VS 2005 did not complain, but in MS VS 2008 it did. I realise that Intel is not responsible for what happens in MS products, so I do not insist on nor expect an answer, however, it will continue to bug me... I was also wondering whether the STDCALL attribute is in fact correct when in the settings of the project one indicates CVF as the calling convention...Thanks again for those who helped.l8r

Steve Lionel (Intel)'s picture

I doubt that the VS version was actually significant. I might believe that the compiler version was. In the past, we have had issues where the compiler did not correctly account for character arguments when determining the STDCALL suffix, and I have a vague recollection of it being related to use of the non-standard Microsoft INTERFACE TO syntax. It's also possible that use of the "check routine interfaces" feature affects this - we've had bugs in the past there too. I'm not aware of any such issues in the current (or even recent 11.1) produicts.

If you can come up with a self-contained test case, we'd like to see it.

However, I am puzzled that you get a wrong name with an explicit ALIAS that includes the @24 suffix. This implies to me that the compiler did not see your interface and just used the defaults. That the routine and CTY have REFERENCE should prevent the compiler from believing there is a passed length argument.

/iface:CVF adjusts several calling convention attributes:

- STDCALL rather than C
- MIXED_STR_LEN_ARG rather than NOMIXED_STR_LEN_ARG
- Arguments passed by reference and names upcased (just saying STDCALL uses value and lowercase)

Steve

Thanks Steve for your comments and also explaining the aspects concerning STDCALL and CF calling convention.Concerning the provision of a code example, this would only make sense if I could also inlcude the CVF dll, its lib and the include file that defines the interfaces. There is no problem in providing my code or even the example, but I cannot distribute the dll and its lib. I really apologise for this, but it is not mine to distribute.However, in the meantime, some more interesting results have come to light. If the project, source code and its settings remain the same as discussed before, but in the original include file (i.e. not the one destined for the DEC compiler) three lines of directives are removed at the very beginning and end of the file, e.g.:$if .not. defined (_IDWM32AFI_)$define _IDWM32AFI_...different procedure interface definitions....$endifthen the project compiles and links without any errors. Normally these three lines are required in the case where one has a mixed Fortran/C project and their absence would generate an error. So I have no idea how it is possible that removing these seemingly innocent lines could have such a strange behaviour from the linker.

Steve Lionel (Intel)'s picture

All we would need is a compilable source (and the command you use to compile it) - it is not necessary to link or run the program to see the problem.

Steve

Thanks again Steve for your interest. Right, I have two simple example source files:__________________program call_idwm!implicit none!real::rlon, rlat, dmin1m, dazim, rangemcharacter(len = 3)::cnt1!rlon = 0.5rlat = 0.25rangem = 1500.0!call my_GEODW1(rlon, rlat, rangem, cnt1, dmin1m, dazim)!end program call_idwm___________________________and__________________________________subroutine my_GEODW1(rlon, rlat, rangem, cnt1, dmin1m, dazim)!implicit none!include 'IDWM32.FI'!real::rlon, rlat, dmin1m, dazim, rangemcharacter(len = 3)::cnt1!call GEODW1(rlon, rlat, rangem, cnt1, dmin1m, dazim)!end subroutine my_GEODW1!subroutine additional_subend subroutine additional_sub_______________________With the code above and the include file IDWM32.FI containing the first two and last lines of this section:___________________________$if .not. defined (_IDWM32AFI_)$define _IDWM32AFI_ INTERFACE TO SUBROUTINE GEODW1 (RLONG,RLAT,RANGE,CTY,XDST,XAZI)!MS$ ATTRIBUTES DLLEXPORT :: GEODW1!MS$ ATTRIBUTES STDCALL, REFERENCE, ALIAS: '_GEODW1@24' :: GEODW1!MS$ ATTRIBUTES REFERENCE :: CTY REAL*4 RLONG, RLAT, RANGE, XDST, XAZI CHARACTER*3 CTY END$endif___________________________________The program compiles with no errors and I get the link error:Error 1 error LNK2019: unresolved external symbol _GEODW1@28 referenced in function _MY_GEODW1 call_idwm_direct.obj Error 2 fatal error LNK1120: 1 unresolved externals Debug\test_IDWM.exe

If I remove the lines:subroutine additional_subend subroutine additional_subfrom the second source file, then program links with no error, or if I comment out the first two lines and the last line in the include file, but keep the last two lines in the second source file, then the program also links without an error. I never have compile errors in any of the cases. Running the executable in the case that I have one gives the expected result.As I already explained, without the lib and dll, I do not see what you can prove with this code as it will not compile if you do not have these files and so you will not get to the linking stage, which is where I have my difficulties.Thanks again.

Steve Lionel (Intel)'s picture

I don't need to link - I can examine the symbols generated by the object code. I'll take a look at this next week.

Steve
Steve Lionel (Intel)'s picture

I can see at least one problem - the compiler is not properly processing the $if block when the $define is present. I will report this to the developers. The simplest workaround is to remove the $IF, $DEFINE and $ENDIF from the .fi file. I would also recommend using the following for the .fi file:

INTERFACE
SUBROUTINE GEODW1 (RLONG,RLAT,RANGE,CTY,XDST,XAZI)
!MS$ ATTRIBUTES DLLEXPORT :: GEODW1
!MS$ ATTRIBUTES STDCALL, REFERENCE, DECORATE, ALIAS: 'GEODW1' :: GEODW1
!MS$ ATTRIBUTES REFERENCE :: CTY
REAL*4 RLONG, RLAT, RANGE, XDST, XAZI
CHARACTER*3 CTY
END SUBROUTINE
END INTERFACE

Steve

Thanks Steve for this information and also for the recommendation. I shall talk to my colleagues who produce the old CVF dll and are also responsible for the .fi file.

Login to leave a comment.