locked
Moving project to VS2015 - solving linker errors RRS feed

  • Question

  • Hi,

    I have a small command line program that I have until now been developing under VS2013 in Windows 7. It uses Maxim's One Wire Public Domain API and WinUSB. It builds perfectly well under VS2013. Now I am trying to move it to a new computer running Windows 8.1 and VS2015. When I try to build it in this environment, it fails with the following linker errors:

    1>------ Build started: Project: readtemp5, Configuration: Debug Win32 ------
    1>presshum.obj : warning LNK4217: locally defined symbol _printf imported in function _print_array
    1>readtemp.obj : warning LNK4049: locally defined symbol _printf imported
    1>presshum.obj : warning LNK4217: locally defined symbol _sprintf_s imported in function _ReadPressHum
    1>readtemp.obj : warning LNK4049: locally defined symbol _sprintf_s imported
    1>temp10.obj : warning LNK4049: locally defined symbol _sprintf_s imported
    1>presshum.obj : warning LNK4217: locally defined symbol _sprintf imported in function _ReadPressHum
    1>temp10.obj : warning LNK4049: locally defined symbol _sprintf imported
    1>readtemp.obj : warning LNK4217: locally defined symbol _fprintf imported in function _main
    1>readtemp.obj : error LNK2019: unresolved external symbol __imp____iob_func referenced in function _main
    1>readtemp.obj : error LNK2019: unresolved external symbol __imp__scanf referenced in function _mainx
    1>readtemp.obj : error LNK2019: unresolved external symbol __imp__sscanf referenced in function _main
    1>readtemp.obj : error LNK2001: unresolved external symbol _owErrorStack
    1>readtemp.obj : error LNK2001: unresolved external symbol _owErrorPointer
    1>readtemp.obj : error LNK2001: unresolved external symbol _owErrorMsg
    1>D:\XPS_8700 Extended Files\Users\RowanB\Documents\Visual Studio 2015\Projects\readtemp5\readtemp5\Debug\readtemp5.exe : fatal error LNK1120: 6 unresolved externals
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

    I suppose that this means that I do not have some library or DLL on the new computer, or it is not in the location expected, or that I have failed to set up some project properties correctly to point to the files on the new system. I have installed WDK on the new computer, but it didn't put the files in the same place as they were on the old one (in C:\WinDDK). I can't actually find the files at all... Where should they be in Win8.1/VS2015?

    What does the error message "locally defined symbol XXX imported" actually mean?

    What are the rules for the symbols with underscores in them? How do I find the original symbols that are giving rise to these errors?

    I really need some help to know how to solve this problem or how to investigate further what is wrong.

    Thanks for your help.

    Rowan


    Friday, October 28, 2016 11:29 AM

All replies

  • From https://msdn.microsoft.com/en-us/library/bb531344.aspx

    • The printf and scanf family of functions are now defined inline. The definitions of all of the printf and scanf functions have been moved inline into <stdio.h>, <conio.h>, and other CRT headers. This is a breaking change that leads to a linker error (LNK2019, unresolved external symbol) for any programs that declared these functions locally without including the appropriate CRT headers. If possible, you should update the code to include the CRT headers (that is, add #include <stdio.h>) and the inline functions, but if you do not want to modify your code to include these header files, an alternative solution is to add an additional library to your linker input, legacy_stdio_definitions.lib.

      To add this library to your linker input in the IDE, open the context menu for the project node, choose Properties, then in the Project Properties dialog box, choose Linker, and edit the Linker Input to add legacy_stdio_definitions.lib to the semi-colon-separated list.

      If your project links with static libraries that were compiled with a release of Visual C++ earlier than 2015, the linker might report an unresolved external symbol. These errors might reference internal stdio definitions for _iob, _iob_func, or related imports for certain stdio functions in the form of _imp_*. Microsoft recommends that you recompile all static libraries with the latest version of the Visual C++ compiler and libraries when you upgrade a project. If the library is a third-party library for which source is not available, you should either request an updated binary from the third party or encapsulate your usage of that library into a separate DLL that you compile with the older version of the Visual C++ compiler and libraries.

      System_CAPS_warningWarning

      If you are linking with Windows SDK 8.1 or earlier, you might encounter these unresolved external symbol errors. In that case, you should resolve the error by adding legacy_stdio_definitions.lib to the linker input as described previously.

      To troubleshoot unresolved symbol errors, you can try using dumpbin.exe to examine the symbols defined in a binary. Try the following command line to view symbols defined in a library.

      dumpbin.exe /LINKERMEMBER somelibrary.lib
      

    Friday, October 28, 2016 3:18 PM
  • Thank you, that is extremely useful. It has removed some of the errors, but not all. I now get:

    1>------ Build started: Project: readtemp5, Configuration: Debug Win32 ------

    1>readtemp.obj : error LNK2019: unresolved external symbol __imp____iob_func referenced in function _main

    1>readtemp.obj : error LNK2001: unresolved external symbol _owErrorStack

    1>readtemp.obj : error LNK2001: unresolved external symbol _owErrorPointer

    1>readtemp.obj : error LNK2001: unresolved external symbol _owErrorMsg

    1>D:\XPS_8700 Extended Files\Users\RowanB\Documents\Visual Studio 2015\Projects\readtemp5\readtemp5\Debug\readtemp5.exe : fatal error LNK1120: 4 unresolved externals

    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

    AS far as I can see, I have defined _owErrorStack, _owErrorPointer and _owErrorMsg in one of my source files. Why is it not seeming to find these symbols?

    And why is it reporting __imp____iob_func  as unresolved?

    Many thanks - Rowan

    Friday, October 28, 2016 5:19 PM
  • Can you show us how you declared and defined the _owErrorStack, _owErrorPointer and _owErrorMsg symbols in your source (show relevant code in .cpp and .h files).

    As far as _imp__iob_func goes  is there an import library that needs to be included for the linker?  Perhaps something for some third party software you are using?

    Friday, October 28, 2016 5:27 PM
  • Thanks for your reply.

    Here is the source defining the symbols in question. It is in file owerr.c

    owErrorStruct owErrorStack[SIZE_OWERROR_STACK];

    int owErrorPointer = 0;

       char *owErrorMsg[125] =
       {
       /*000*/ "No Error Was Set",
       /*001*/ "No Devices found on 1-Wire Network",
       /*002*/ "1-Wire Net Reset Failed",
       /*003*/ "Search ROM Error: Couldn't locate next device on 1-Wire",
       /*004*/ "Access Failed: Could not select device",
       /*005*/ "DS2480B Adapter Not Detected",
       /*006*/ "DS2480B: Wrong Baud",
       /*007*/ "DS2480B: Bad Response",
       /*008*/ "Open COM Failed",
       /*009*/ "Write COM Failed",
       /*010*/ "Read COM Failed",
       /*011*/ "Data Block Too Large",
       /*012*/ "Block Transfer failed",
       /*013*/ "Program Pulse Failed",
       /*014*/ "Program Byte Failed",
       /*015*/ "Write Byte Failed",
       /*016*/ "Read Byte Failed",
       /*017*/ "Write Verify Failed",
       /*018*/ "Read Verify Failed",
       /*019*/ "Write Scratchpad Failed",
       /*020*/ "Copy Scratchpad Failed",
       /*021*/ "Incorrect CRC Length",
       /*022*/ "CRC Failed",
       /*023*/ "Failed to acquire a necessary system resource",
       /*024*/ "Failed to initialize system resource",
       /*025*/ "Data too long to fit on specified device.",
       /*026*/ "Read exceeds memory bank end.",
       /*027*/ "Write exceeds memory bank end.",
       /*028*/ "Device select failed",
       /*029*/ "Read Scratch Pad verify failed.",
       /*030*/ "Copy scratchpad complete not found",
       /*031*/ "Erase scratchpad complete not found",
       /*032*/ "Address read back from scrachpad was incorrect",
       /*033*/ "Read page with extra-info not supported by this memory bank",
       /*034*/ "Read page packet with extra-info not supported by this memory bank",
       /*035*/ "Length of packet requested exceeds page size",
       /*036*/ "Invalid length in packet",
       /*037*/ "Program pulse required but not available",
       /*038*/ "Trying to access a read-only memory bank",
       /*039*/ "Current bank is not general purpose memory",
       /*040*/ "Read back from write compare is incorrect, page may be locked",
       /*041*/ "Invalid page number for this memory bank",
       /*042*/ "Read page with CRC not supported by this memory bank",
       /*043*/ "Read page with CRC and extra-info not supported by this memory bank",
       /*044*/ "Read back from write incorrect, could not lock page",
       /*045*/ "Read back from write incorrect, could not lock redirect byte",
       /*046*/ "The read of the status was not completed.",
       /*047*/ "Page redirection not supported by this memory bank",
       /*048*/ "Lock Page redirection not supported by this memory bank",
       /*049*/ "Read back byte on EPROM programming did not match.",
       /*050*/ "Can not write to a page that is locked.",
       /*051*/ "Can not lock a redirected page that has already been locked.",
       /*052*/ "Trying to redirect a locked redirected page.",
       /*053*/ "Trying to lock a page that is already locked.",
       /*054*/ "Trying to write to a memory bank that is write protected.",
       /*055*/ "Error due to not matching MAC.",
       /*056*/ "Memory Bank is write protected.",
       /*057*/ "Secret is write protected, can not Load First Secret.",
       /*058*/ "Error in Reading Scratchpad after Computing Next Secret.",
       /*059*/ "Load Error from Loading First Secret.",
       /*060*/ "Power delivery required but not available",
       /*061*/ "Not a valid file name.",
       /*062*/ "Unable to Create a Directory in this part.",
       /*063*/ "That file already exists.",
       /*064*/ "The directory is not empty.",
       /*065*/ "The wrong type of part for this operation.",
       /*066*/ "The max len for this file is too small.",
       /*067*/ "This is not a write once bank.",
       /*068*/ "The file can not be found.",
       /*069*/ "There is not enough space available.",
       /*070*/ "There is not a page to match that bit in the bitmap.",
       /*071*/ "There are no jobs for EPROM parts.",
       /*072*/ "Function not supported to modify attributes.",
       /*073*/ "Handle is not in use.",
       /*074*/ "Tring to read a write only file.",
       /*075*/ "There is no handle available for use.",
       /*076*/ "The directory provided is an invalid directory.",
       /*077*/ "Handle does not exist.",
       /*078*/ "Serial Number did not match with current job.",
       /*079*/ "Can not program EPROM because a non-EPROM part on the network.",
       /*080*/ "Write protect redirection byte is set.",
       /*081*/ "There is an inappropriate directory length.",
       /*082*/ "The file has already been terminated.",
       /*083*/ "Failed to read memory page of iButton part.",
       /*084*/ "Failed to match scratchpad of iButton part.",
       /*085*/ "Failed to erase scratchpad of iButton part.",
       /*086*/ "Failed to read scratchpad of iButton part.",
       /*087*/ "Failed to execute SHA function on SHA iButton.",
       /*088*/ "SHA iButton did not return a status completion byte.",
       /*089*/ "Write data page failed.",
       /*090*/ "Copy secret into secret memory pages failed.",
       /*091*/ "Bind unique secret to iButton failed.",
       /*092*/ "Could not install secret into user token.",
       /*093*/ "Transaction Incomplete: signature did not match.",
       /*094*/ "Transaction Incomplete: could not sign service data.",
       /*095*/ "User token did not provide a valid authentication response.",
       /*096*/ "Failed to answer a challenge on the user token.",
       /*097*/ "Failed to create a challenge on the coprocessor.",
       /*098*/ "Transaction Incomplete: service data was not valid.",
       /*099*/ "Transaction Incomplete: service data was not updated.",
       /*100*/ "Unrecoverable, catastrophic service failure occured.",
       /*101*/ "Load First Secret from scratchpad data failed.",
       /*102*/ "Failed to match signature of user's service data.",
       /*103*/ "Subkey out of range for the DS1991.",
       /*104*/ "Block ID out of range for the DS1991",
       /*105*/ "Password is enabled",
       /*106*/ "Password is invalid",
       /*107*/ "This memory bank has no read only password",
       /*108*/ "This memory bank has no read/write password",
       /*109*/ "1-Wire is shorted",
       /*110*/ "Error communicating with 1-Wire adapter",
       /*111*/ "CopyScratchpad failed: Ending Offset must go to end of page",
       /*112*/ "WriteScratchpad failed: Ending Offset must go to end of page",
       /*113*/ "Mission can not be stopped while one is not in progress",
       /*114*/ "Error stopping the mission",
       /*115*/ "Port number is outside (0,MAX_PORTNUM) interval",
       /*116*/ "Level of the 1-Wire was not changed",
       /*117*/ "Both the Read Only and Read Write Passwords must be set",
       /*118*/ "Failure to change latch state."
       /*119*/ "Could not open usb port through libusb",
       /*120*/ "Libusb DS2490 port already opened",
       /*121*/ "Failed to set libusb configuration",
       /*122*/ "Failed to claim libusb interface",
       /*123*/ "Failed to set libusb altinterface",
       /*124*/ "No adapter found at this port number"
       };

    Here are some extracts from my owerr.h file that is included in my other source files when required:

    extern owErrorStruct owErrorStack[SIZE_OWERROR_STACK];

    extern int owErrorPointer;

    extern char *owErrorMsg[];

    I presume there is nothing wrong with this, as otherwise the modules would fail to compile, wouldn't they, and they don't, i.e. they compile fine. It is the linking where it fails.

    W.r.t.  _imp__iob_func it is possible that in the VS2015 project I have omitted some library (I can't precisely remember what I had to include to get the VS2013 project to build successfully - it was some time ago), but how do I identify which one? What would have been the original symbol that ended up as  _imp__iob_func? And how do I find a library that contains the missing function? Can it be searched for? How?

    This whole project used to build fine under VS2013, sao there is nothing fundamental wrong with it...

    Thanks - Rowan


    Friday, October 28, 2016 6:17 PM
  • The symbols in question are global variables and not local variables on the stack?

    Are all libraries and included headers from VS2015? See https://connect.microsoft.com/VisualStudio/feedback/details/1144980/error-lnk2001-unresolved-external-symbol-imp-iob-func

    In the VS2015 project options turn on the setting to show linker progress.  Maybe we'll get a clue.


    • Edited by RLWA32 Friday, October 28, 2016 7:53 PM added link
    • Proposed as answer by Hart Wang Monday, October 31, 2016 2:29 AM
    Friday, October 28, 2016 7:06 PM
  • Yes. They are defined at top level (i.e. not inside any functions) in owerr.c, and declared in owerr.h that is included in each source file that uses them.

    Rowan

    Saturday, October 29, 2016 6:31 AM
  • Is the readtemp.c source file including the correct version  of the owerr.h header?

    You might also consider creating a brand new solution/project in VS2015 and then adding your existing source code to it.  That often solves migration problems from older versions of VS.

    • Edited by RLWA32 Saturday, October 29, 2016 4:09 PM added suggestion
    Saturday, October 29, 2016 10:20 AM
  • Thanks for your suggestions.

    What do you mean by "the correct version of owerr.h"? Which other version might it be including? How do I check which version it is actually using?

    I have in any case renamed the only other copy I could find of owerr.h to something else, and it still builds, and generates the same errors.

    I will try creating a new solution, and adding my souirce to it (and setting up all the project properties correctly when I have a bit of time.

    Thanks - Rowan

    Sunday, October 30, 2016 6:57 AM
  • Hi RowanSylvester-Bradley,

    I also think you need to create a new solution. From the previous reply.

    It has not been a supported scenario to compile source files with one version of the Visual

    C++ libraries headers and link with a different version of the Visual C++ libraries.

    Best Regards,

    Hart


    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, October 31, 2016 2:29 AM