I have been updating a big working C++ Windows application in Visual Studio 2022 into several static libs.
The idea is to share part of the code to an external developer, and not share the complete C++ files of the project. Only part of the code would be shared, and the rest would be .lib's and .h's.
The structure of the entire solution is:
External LIB
Library 1 LIB - Referencing .h's from the External LIB
Application EXE - Using the above libs
When building the application EXE, the link fails with thousands of errors of missing symbols from the External LIB. "LNK2001 unresolved external symbol "__declspec(dllimport) public: bool __thiscall ..."
1>Common.lib(LocalizedString.obj) : error LNK2001: unresolved external symbol "__declspec(dllimport) public: bool __thiscall cocos2d::Value::isNull(void)const " (__imp_?isNull#Value#cocos2d##QBE_NXZ)
1> Hint on symbols that are defined and could potentially match:
1> "__declspec(dllimport) public: bool __thiscall cocos2d::Data::isNull(void)const " (__imp_?isNull#Data#cocos2d##QBE_NXZ)
The EXE is configured to include all the libs (configured in VS project settings: Additional Dependencies).
All the projects are being built with __cdecl (/Gd) and Multi-threaded Debug DLL (/MDd).
If I add to the EXE code some dummy declarations of symbols that are being referred into the "unresolved external symbol" error, Visual Studio adds those symbols and I can see the number of errors decreasing. But this is not a good solution...
It looks like somehow Visual Studios is adding all the symbols automatically.
I believe this whole issue may be related with the following. When building my libs I get the following "warning LNK4006: XXXX already defined in XXXXX.lib(xxhash.obj); second definition ignored".
I have tried different project settings, like "Link Library Dependencies: Yes". But nothing seems to fix it.
I'm stuck with this for two days... Can someone save me?
Found the problem. There was an hidden define in the external lib adding the dllimport to every external class.
#if defined(CC_STATIC)
#define CC_DLL
#else
#if defined(_USRDLL)
#define CC_DLL __declspec(dllexport)
#else /* use a DLL library */
#define CC_DLL __declspec(dllimport)
#endif
#endif
Related
Attempting to link in libyaml (0.2.5) using Visual Studio 2019 Enterprise and CMake, as I have a cross-platform (Linux/Windows) project that uses this library. According to the documentation, this library should work in Windows 10. It links in just fine on Linux (64-bit machine).
I'm compiling it as a static lib, and it has no issue generating the .lib file. I've copied it to the appropriate location that I'm linking in from my CMakelists.txt, as well as the header.
When I link it in from my project on Windows:
ts.lib(yamlparser.cxx.obj) : error LNK2019: unresolved external symbol __imp_yaml_parser_initialize referenced in function "public: bool __cdecl YAMLParser::parse_cfg(void)" (?parse_cfg#YAMLParser##QEAA_NXZ)
ts.lib(yamlparser.cxx.obj) : error LNK2019: unresolved external symbol __imp_yaml_parser_set_input_file referenced in function "public: bool __cdecl YAMLParser::parse_cfg(void)" (?parse_cfg#YAMLParser##QEAA_NXZ)
ts.lib(yamlparser.cxx.obj) : error LNK2019: unresolved external symbol __imp_yaml_parser_scan referenced in function "public: bool __cdecl YAMLParser::parse_cfg(void)" (?parse_cfg#YAMLParser##QEAA_NXZ)
This is what I'm doing on the CMake side - the very same thing I'm doing to link in my GoogleTest libraries on both Linux and Windows:
if (UNIX)
...
...
else()
set (MY_LIB_DIR "C:/mylib/lib")
set (MY_INCLUDE "C:/mylib/include")
set (YAML_LIB "${MY_LIB_DIR}/yaml.lib")
set (VCPKG_LIBRARY_LINKAGE static)
endif()
include_directories(${MY_INCLUDE})
add_library(ts
...
...
)
add_executable(myexec main.cxx)
target_link_libraries(myexec ts ${YAML_LIB})
VS isn't giving me many clues here except that there's a linkage problem that I can't quite figure out.
Any advice on how I can debug this or what the problem may be?
The __imp was the clue that my code was trying to include the library dynamically... Opening up yaml.h, I noticed that it tries to export from DLL unless YAML_DECLARE_STATIC is defined. Defined this in CMake and my issue is resolved.
I was wondering if anyone has had success linking against Tensorflow 2.3 DLL on Windows.
I am trying to integrate some tensorflow functionality in a tiny VS2019 test project to see if I can use tensorflow C++ API at all.
I managed to build tensorflow with MSVC 14.16.27023 and followed the instructions given in the official links:
https://docs.bazel.build/versions/master/windows.html#build-c
https://www.tensorflow.org/install/source_windows
I built .dll and .lib using the following Bazel commands:
bazel build --config=opt //tensorflow:tensorflow.dll
bazel build --config=opt //tensorflow:tensorflow.lib
VS2019 project properties:
add relevant Additional Include Directories
add Additional Library Directories, which is only path-to-tensorflow-source\bazel-bin\tensorflow, where bazel-bin directory is generated by the build system (ie Bazel)
in Linker->Input->Additional Dependencies add generated tensorflow.lib
The source code is tiny and is comprised of a few lines I looked up in Joe Antognini's example:
#pragma once
#define NOMINMAX
#include "tensorflow/core/public/session.h"
#include "tensorflow/cc/ops/standard_ops.h"
int main()
{
tensorflow::Scope root = tensorflow::Scope::NewRootScope();
auto X = tensorflow::ops::Placeholder(root.WithOpName("x"), tensorflow::DT_FLOAT,
tensorflow::ops::Placeholder::Shape({ -1, 2 }));
}
As explained in Ashley Tharp's guide, building right away results in linker errors complaining about unresolved external symbols:
LNK2001 unresolved external symbol "private: class tensorflow::Scope __cdecl tensorflow::Scope::WithOpNameImpl(...
LNK2001 unresolved external symbol "public: static class tensorflow::Scope __cdecl tensorflow::Scope::NewRootScope(void)"...
LNK2001 unresolved external symbol "public: __cdecl tensorflow::Scope::~Scope(void)"...
LNK2001 unresolved external symbol "public: __cdecl tensorflow::ops::Placeholder::Placeholder(...
Here is the explanation from her guide:
The reason this is happening is because you can only expose 60,000 symbols in a dll. This is just some limitation of the dll format. The tensorflow library code has more than 60000 symbols, so as the programmer building this dll (a dll is just a binary file for accessing a library at runtime) you will have to manually indicate which symbols you want exposed if they are not already. Google has chosen some default set, but it may not work for everyone.
And, as suggested in the guide, I went into tensorflow headers and prepended relevant symbols with TF_EXPORT macro, which is your usual DLL import-export pattern:
#ifdef TF_COMPILE_LIBRARY
#define TF_EXPORT __declspec(dllexport)
#else
#define TF_EXPORT __declspec(dllimport)
#endif // TF_COMPILE_LIBRARY
The above-mentioned workaround works for the first 3 errors:
// scope.h
~Scope(); // change to: TF_EXPORT ~Scope();
...
static Scope NewRootScope(); // change to: TF_EXPORT static Scope NewRootScope();
...
Scope WithOpNameImpl(const string& op_name) const; // change to TF_EXPORT Scope...
After I am done editing, I re-run bazel like so bazel build --config=opt //tensorflow:tensorflow.lib, and errors are gone.
However, the issue arises when I try to perform similar manipulation to fix the last remaining unresolved symbol, namely Placeholder. The symbol is located inarray_ops.h, which is a machine-generated file. So whatever I edit inside the file is overwritten and lost as soon as I try to build .lib.
Question: How can I expose symbols that appear in machine-generated files? Pointers in the right direction would be much appreciated, perhaps I'm missing something obvious.
The folder containing dynamic library tensorflow_cc.dll and import library tensorflow_cc.dll.if.lib has also two files:
tensorflow_filtered_def_file.def : contains import symbols
tensorflow_cc.dll-2.params : has all built libraries
now if you have some unresolved symbols when building your app, all you have to do is to rebuild dynamic-library with updated tensorflow_filtered_def_file.def file. To this file you have to add missing symbols, for your sample code, it is:
EXPORTS
??1Scope#tensorflow##QEAA#XZ
?NewRootScope#Scope#tensorflow##SA?AV12#XZ
??0Placeholder#ops#tensorflow##QEAA#AEBVScope#2#W4DataType#2#AEBUAttrs#012##Z
?WithOpNameImpl#Scope#tensorflow##AEBA?AV12#AEBV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###Z
the rest symbols ...
After you updated .def file, you rebuild dll by calling the following command:
link.exe /nologo /DLL /SUBSYSTEM:CONSOLE -defaultlib:advapi32.lib -DEFAULTLIB:advapi32.lib
-ignore:4221 /FORCE:MULTIPLE /MACHINE:X64
#bazel-out/x64_windows-opt/bin/tensorflow/tensorflow_cc.dll-2.params /OPT:ICF /OPT:REF
/DEF:bazel-out/x64_windows-opt/bin/tensorflow/tensorflow_filtered_def_file.def /ignore:4070
before rebuilding dll/lib remove these files (they are only read-only).
More info here , see rafix07 comment.
I downloaded and compiled GraphicsMagick, 1.3.23, Q16, x64, StaticMT version. I had to convert the Visual Studio 7 solution generated by GraphicsMagick's build utility to Visual Studio 2015 format. I linked my project to CORE_DB_magick_.lib and CORE_DB_Magick++_.lib.
When the linker ran, it produced unresolved external symbols when linking InitializeMagick() and DestroyMagick()
1>wtd.lib(WebController.obj) : error LNK2019: unresolved external symbol __imp_DestroyMagick referenced in function "public: __cdecl Wt::WebController::~WebController(void)" (??1WebController#Wt##QEAA#XZ)
1>wtd.lib(WebController.obj) : error LNK2019: unresolved external symbol __imp_InitializeMagick referenced in function "public: __cdecl Wt::WebController::WebController(class Wt::WServer &,class std::basic_string,class std::allocator > const &,bool)" (??0WebController#Wt##QEAA#AEAVWServer#1#AEBV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##_N#Z)
I can't understand why the symbols are not being linked. Any ideas?
Apparently, GraphicsMagick Static versions do not link properly.
What is your project type? I had a similar problem when trying to link the GraphicsMagick libraries to a DLL.
The clue here is that __imp is the function decoration for DLL imports, so you're trying to link with DLL functions.
The problem is that the header magick/common.h, when linked to a DLL project, reads the current configuration of the Visual Studio pre-processor environment to determine which mode the library is in, which is obviously wrong if you're trying to link static libraries into your DLL, for example. In this case, it defines MagickExport to __declspec(dllimport).
AFAIK this is a bug in the library. For proper static build support, magick/common.h needs to do something like read information from the magick/magick_config.h to determine what mode the library was actually built in and define MagickExport appropriately.
Since your library is statically linked, you can fix this by commenting out everything in the define:
#if defined(MSWINDOWS) && !defined(__CYGWIN__)
and replacing it with:
#define MagickExport
#define ModuleExport
#define MagickGlobal
Well i basically inherited a bunch of code that i was told to fix because it used to work a few months ago but it doesn't at the moment. The program itself seems to be riddled with linking errors and i was able to fix some of them. However I have run across a LNK2019 unresolved external _imp error where some function utilized in the main is not resolved. due to the "_imp" i am assuming that it is a problem related to importing from .dll or .lib files.
First of all i have three .lib files which i believe am importing them correctly into VS2010 and i have configured the platform to be 64x. There is also .dll files that correspond with the .lib files. The .h file that contains the declaration for these error ridden functions contain something like
ILAPI void ILAPIENTRY ilDeleteImage(const ILuint Num);
unfortunately i would be guessing that the definition is defined in the .dll file which i did not write myself so i am unsure. But since this is code that worked before i believe that i am getting this error because the linker can't find the definition rather than def/decl not matching reason.
when i hover over the ILAPI it states: "ILAPI __declspec(dllimport)"
My current guess is that the program imports the .lib files and the .lib files use the .dll files to get the definition of the functions. I believe that i am importing the .lib files since the compiler no longer keeps on telling me that it can't find specific .lib files. However i am concerned that it may not be connecting the the .dll files. I am some what unsure. I have opened the .lib files and the .lib files contain the names of the functions that are giving errors. I have also used the dependency walker program to look at my DLL files and it has been giving me some of the following errors:
Error: At least one module has an unresolved import due to a missing export function in an implicitly dependent module.
Error: Modules with different CPU types were found.
Based on other peoples comments i feel like i can ignore the 2nd error. But i am unsure of the first error. I am also unsure if that would be the root cause of the problem. It may or may not be.
I have also looked inside the .lib files using VS cmd and dependency walker and it seems like the names of the functions that can't be found are listed in one of the .lib and .dll.
In terms of configuration I am running on release mode x64 platform.
I have added "DevIL.lib ILU.lib ILUT.lib " library functions in the proj -> prop -> linker -> commandline. I have also added the path for linker -> general -> additional library directory. I have also tried messing with input additional dependency but it has no effect. The .lib and .dll files are put in the same directory as well. In the proj property configuration i do not mention .dll anywhere (am i supposed to? I've tried in various locations but just creates more error) I understand that there are a ton of posts regarding link 2019 error but i have not had good luck so far in my search for my particular problem. I would appreciate any suggestions, comment, or a link where i may find a clue as in to why this is occuring
here is the linker command from log:
here is the linker command from the build log itself:
Link:
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\x86_amd64\link.exe /ERRORREPORT:PROMPT /OUT:"x64\Release\dff.exe" /VERBOSE /INCREMENTAL /NOLOGO
/LIBPATH:C:\Users\Sub2\Desktop\dff\x64\Release /MANIFEST
/ManifestFile:"x64\Release\dff.exe.intermediate.manifest"
/MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG
/PDB:"C:\Users\Sub2\Desktop\dff\x64\Release\dff.pdb"
/SUBSYSTEM:CONSOLE /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE /NXCOMPAT
/IMPLIB:"x64\Release\dff.lib" /MACHINE:X64
x64\Release\dff.exe.embed.manifest.res
x64\Release\acquisition.obj
x64\Release\azmemutil.obj
x64\Release\dff.obj
x64\Release\fft.obj
x64\Release\FocusMeasure.obj
x64\Release\ge.obj
x64\Release\stdafx.obj DevIL.lib ILU.lib ILUT.lib
1>LINK : warning LNK4075: ignoring '/INCREMENTAL' due to '/OPT:ICF' specification
// This is from Win32's <wingdi.h> and <winnt.h>
#if defined(__LCC__)
#define ILAPI __stdcall
#elif defined(_WIN32) //changed 20031221 to fix bug 840421
#ifdef IL_STATIC_LIB
#define ILAPI
#else
#ifdef _IL_BUILD_LIBRARY
#define ILAPI __declspec(dllexport)
#else
#define ILAPI __declspec(dllimport)
#endif
#endif
#elif __APPLE__
#define ILAPI extern
#else
#define ILAPI
#endif
Also:
#define ILAPIENTRY __stdcall
build log info when it gets close to error:
Found KERNEL32_NULL_THUNK_DATA
Referenced in kernel32.lib(KERNEL32.dll)
Loaded kernel32.lib(KERNEL32.dll)
Searching C:\Users\Sub2\Desktop\dff\x64\Release\DevIL.lib:
Searching C:\Users\Sub2\Desktop\dff\x64\Release\ILU.lib:
Searching C:\Users\Sub2\Desktop\dff\x64\Release\ILUT.lib:
Searching C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\lib\amd64\MSVCRT.lib:
Searching C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\lib\amd64\OLDNAMES.lib:
Searching C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\lib\amd64\msvcprt.lib:
Finished searching libraries
Finished pass 1
Invoking CVTRES.EXE:
/machine:amd64
/verbose
/out:"C:\Users\Sub2\AppData\Local\Temp\lnk92ED.tmp"
/readonly
"x64\Release\dff.exe.embed.manifest.res"
Microsoft (R) Windows Resource To Object Converter Version 10.00.30319.01
Copyright (C) Microsoft Corporation. All rights reserved.
adding resource. type:MANIFEST, name:1, language:0x0409, flags:0x30, size:2
1>dff.obj : error LNK2019: unresolved external symbol __imp_iluGetImageInfo referenced in function main
1>dff.obj : error LNK2019: unresolved external symbol __imp_iluImageParameter referenced in function main
1>dff.obj : error LNK2019: unresolved external symbol __imp_ilDeleteImages referenced in function main
1>dff.obj : error LNK2019: unresolved external symbol __imp_ilSaveImage referenced in function main
1>dff.obj : error LNK2019: unresolved external symbol __imp_iluFlipImage referenced in function main
1>dff.obj : error LNK2019: unresolved external symbol __imp_iluScale referenced in function main
1>dff.obj : error LNK2019: unresolved external symbol __imp_ilTexImage referenced in function main
1>dff.obj : error LNK2019: unresolved external symbol __imp_ilCopyPixels referenced in function main
1>dff.obj : error LNK2019: unresolved external symbol __imp_ilGetError referenced in function main
1>dff.obj : error LNK2019: unresolved external symbol __imp_ilLoadImage referenced in function main
1>dff.obj : error LNK2019: unresolved external symbol __imp_ilBindImage referenced in function main
1>dff.obj : error LNK2019: unresolved external symbol __imp_ilGenImages referenced in function main
1>dff.obj : error LNK2019: unresolved external symbol __imp_ilInit referenced in function main
1>dff.obj : error LNK2019: unresolved external symbol __imp_ilGetInteger referenced in function main
1>dff.obj : error LNK2019: unresolved external symbol __imp_ilEnable referenced in function main
1>dff.obj : error LNK2019: unresolved external symbol __imp_ilOriginFunc referenced in function main
1>x64\Release\dff.exe : fatal error LNK1120: 16 unresolved externals
1>Done Building Project "C:\Users\Sub2\Desktop\dff\dff.vcxproj" (rebuild target(s)) -- FAILED.
Build FAILED.
Just in case i have also tried writing #define _IL_BUILD_LIBRARY but has no effect.
I'm adding an answer here to summarize a bit on the above comments, the probable root cause and finding a solution to the unresolved errors. I'll preface this by saying linkers tend to be dumb low level tools. If the symbols referenced in the object files don't match exactly with the library then the build process bails out with those unresolved errors. Therefore, the author of the dll library and clients using it will need to put in some effort to ensure the symbols agree.
Root Causes
Unresolved errors are usually caused by one of the follow:
Neither the project nor the libraries linked against implement the function for that symbol.
The libraries actually do implement the function but under a differing reference symbol.
The headers for the library aren't preprocessed or decorated correctly thereby causing #2.
The Hunt
Base on what the OP described the dll libraries linked against exposes a C API. It is unclear what calling convention is being followed by the library in question. The exported names in the dll contain plain undecorated function names suggesting a __cdecl convention. The provided corresponding headers, OTOH has a function like:
ILAPI void ILAPIENTRY ilDeleteImage(const ILuint Num);
which expands into this after preprocessing:
__declspec(dllimport) void __stdcall ilDeleteImage(const ILuint Num);
From this you can conclude three possible scenarios:
The unresolved functions follow a __cdecl convention and the provided headers are wrong.
The unresolved functions follow a __stdcall convention and the exported dll names are wrong.
The functions follow __stdcall but are undecorated to look like __cdecl in the dll. This suggest that a .def file might have been used to build the dll in question.
A Sad State of Affair
Unfortunately, the function call convention followed in a win32 dll is in a confusing state of affairs. There's nothing in the language standard, C or C++, that addresses this ABI issue. See my other answer here. The toolchain vendor is free to decorate the names however they like but typcially for __cdecl functions it's plain undecorated or with a prefixed leading _ underscore.
WinAPI functions you find, like in kernel32.dll user32.dll gdi32.dll etc. are also undecorated but yet follow __stdcall. However, MSVC itself decorates __stdcall with a trailing ampersand with total bytes of the parameters(eg. ilDeleteImage#4) thus contributing to the confusion. To override how LINK decorates the functions, you have to provide a .def file that specifies the new name alias. See here for more details.
Finding the Real Convention
Assuming you don't have access to the source used to build the dll, there are two approachs I can think of to identify the real convention used.
Create a minimal test application that calls into the dll functions as if it uses __cdecl and see if it crashes and burns. This is the easier more straightforward method and you don't have to understand assembly to do it.
Second approach, you do the same but insert assembly breakpoints into your test application and run it through the debugger doing single step instructions. Make sure to choose a dll function taking at least one parameter. For example:
// pullin dll headers
// etc..
int main()
{
__asm int 3;
ilDeleteImage(0xdecafbad);
}
This will break and give control back to the debugger right before the dll function call. From here single step at the assembly level until you reach ilDeleteImage's function prologue.
; function prologue
push ebp
mov ebp, esp
; function implemention
; more opcodes here
; ...
; function epilogue
mov esp, ebp
pop ebp
ret 0x8
Check what form of ret is being used on function return. The number argument following the ret mnemonic indicates how much to increment the esp stack pointer. Any number >0 suggestes a __stdcall function. The hypothical disassembly above shows a __stdcall function freeing 8 bytes on the stack which also hints that this function takes 2 arguments.
I had this compile error while building a project using external static libraries, QDBM and PCRE:
_main.obj : error LNK2001: unresolved external symbol __imp__dpversion
_main.obj : error LNK2001: unresolved external symbol __imp__regcomp
I had correctly configured these external projects to build static libraries, but I had forgotten to define the correct preprocessor defines in my own code, which used these libraries, to enable static linking.
So when they imported the headers from QDBM and PCRE, they added a __declspec(dllimport) that shouldn't be there (for static linking), so they were trying to import symbols from DLLs that didn't exist.
I added the missing preprocessor defines to my build system, which fixed the error:
-DQDBM_STATIC -DPCRE_STATIC
Which meant adding the following lines to my CMakeLists.txt file:
# Tell QDBM not to build itself as a DLL, because we want to link statically to it.
target_compile_definitions(qdbm PUBLIC -DQDBM_STATIC)
target_compile_definitions(lib_common PUBLIC -DPCRE_STATIC)
Okay, here's the thing. I have all the IL files I need, namely
DevIL.dll
DevIL.lib
ILU.dll
ILU.lib
ILUT.dll
ILUT.lib
config.h
config.h.in
devil_cpp_wrapper.h
devil_internal_exports.h
il.h
ilu.h
ilu_region.h
ilut.h
ilut_config.h
My project directory looks like this, let's say my project's name is "Project1"
|-Debug---Project1.pdb
|
| |---Debug---[loads of files]
| |
| |---Glut---[OpenGL files]
| |
| |---IL---[all the files mentioned above]
|-Project1---|
| |---image.bmp
Project Folder---| |
| |---[header and .cpp files I made in the project]
| |
| |---[files produced by Visual Studio]
|
|-ipch---[unrelated stuff]
|
|-Project1.sln
|
|-[other files VS created]
I've put all the DevIL files in the IL folder, as mentioned, and I am sure I am using the unicode compatible versions of them, as I am using Unicode Character Set for the project. In my "Additional Dependencies" I have
ilut.lib; ilu.lib; DevIL.lib;
So, the dependencies are there, I know that's not the problem.
After all that, I am still getting linker errors, mainly LNK2019:unresolved external symbol__imp_ for all the IL functions.
What am I missing? It looks to me like maybe something to do with the project properties or the files themselves...maybe I missed a file?
EDIT: Here is the output messages
1>------ Build started: Project: Final Year Project, Configuration: Debug Win32 ------
1>Build started 29/4/2011 12:46:04 pm.
1>InitializeBuildStatus:
1> Touching "Debug\Final Year Project.unsuccessfulbuild".
1>ClCompile:
1> Main.cpp
1>c:\users\xxxx\desktop\final year project 0.2\final year project\main.cpp(152): warning C4390: ';' : empty controlled statement found; is this the intent?
1>c:\users\xxxx\desktop\final year project 0.2\final year project\main.cpp(141): warning C4101: 'alpha' : unreferenced local variable
1>ManifestResourceCompile:
1> All outputs are up-to-date.
1>Main.obj : error LNK2019: unresolved external symbol __imp__ilInit#0 referenced in function "public: static void __cdecl Main::Init(int,char * *)" (?Init#Main##SAXHPAPAD#Z)
1>Main.obj : error LNK2019: unresolved external symbol __imp__ilDeleteImages#8 referenced in function "public: static void __cdecl Main::DisplayScene(void)" (?DisplayScene#Main##SAXXZ)
1>Main.obj : error LNK2019: unresolved external symbol __imp__ilGetData#0 referenced in function "public: static void __cdecl Main::DisplayScene(void)" (?DisplayScene#Main##SAXXZ)
1>Main.obj : error LNK2019: unresolved external symbol __imp__ilConvertImage#8 referenced in function "public: static void __cdecl Main::DisplayScene(void)" (?DisplayScene#Main##SAXXZ)
1>Main.obj : error LNK2019: unresolved external symbol __imp__ilGetInteger#4 referenced in function "public: static void __cdecl Main::DisplayScene(void)" (?DisplayScene#Main##SAXXZ)
1>Main.obj : error LNK2019: unresolved external symbol __imp__ilLoadImage#4 referenced in function "public: static void __cdecl Main::DisplayScene(void)" (?DisplayScene#Main##SAXXZ)
1>Main.obj : error LNK2019: unresolved external symbol __imp__ilBindImage#4 referenced in function "public: static void __cdecl Main::DisplayScene(void)" (?DisplayScene#Main##SAXXZ)
1>Main.obj : error LNK2019: unresolved external symbol __imp__ilGenImages#8 referenced in function "public: static void __cdecl Main::DisplayScene(void)" (?DisplayScene#Main##SAXXZ)
1>C:\Users\xxxx\Desktop\Final Year Project 0.2\Debug\Final Year Project.exe : fatal error LNK1120: 8 unresolved externals
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:01.93
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Since you added the build output, the answer is now easy: your linker errors have nothing to do with DevIL at all.
You need to link to SDL (Simple DirectMedia Layer).
Since SDL has a C interface, and - IIRC - doesn't require that the DLL uses the same heap as the application, the VC8 version of the "Development Libraries" should do fine (even if you use VC10). Just add SDL.lib to the "Additional Dependencies" and you should be fine.
EDIT
OK.
You're either
not linking against the required .lib files (DevIL.lib etc.) or
linking against corrupted/wrong .lib files
At least there is no other explanation I can think of.
The names mentioned in your build log (__imp__ilInit#0 etc.) are correct, and the current "DevIL SDK" (DevIL 1.7.8 SDK for 32-bit Windows) works fine with VC10 (I just verified it).
To assure you're linking against DevIL.lib etc. please put the following in your main.cpp file:
#pragma comment(lib, "DevIL.lib")
#pragma comment(lib, "ILU.lib")
#pragma comment(lib, "ILUT.lib")
To make sure you're linking against the correct version of those files, re-download the whole SDK and try again with the new files.
EDIT 2
Since I got half the reward, I feel I should be more helpful :)
One last thing you can try: enable verbose linker output to check if the linker finds the correct version of DevIL.lib. (If it didn't find any DevIL.lib, you would get an error LNK1104: cannot open file 'DevIL.lib' - and since you're not getting that message, that cannot be the problem.)
To enable verbose linker output, add the /VERBOSE switch (under Configuration Settings -> Linker -> Command Line -> Additional Options).
That will give you a ton of messages. Copy them into your favorite editor, and search for lines containing DevIL.lib. One of the lines should read Searching X:\path\to\DevIL.lib: - that's the path to the copy of DevIL.lib the linker is using. If that's not the path where you copied the files from the SDK you downloaded, you have found the problem.
And if there are no lines containing DevIL.lib, then the linker isn't even trying to locate it. However I've never seen #pragma comment fail, so if you indeed added those lines that almost surely cannot be the case.
BTW: please let me know if you managed to solve this. This is so strange that I really want to know what was going on :)
You need to tell the linker to link against the IL libs.
Project settings, Linker, Input
Make sure the directory the libs are in is in the Additional directorys field too.
I've noticed your config.h.in file should have .win extension because that it is in DevIL-SDK-x86-1.7.8.zip package. And there's no devil_cpp_wrapper.h file also.
Finally i solved this in this way:
Header files
config.h
config.h.win
devil_internal_exports.h
il.h
il_wrap.h
ilu.h
ilu_region.h
ilut.h
ilut_config.h
goes to VC include directory - all in one directory named IL (c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\IL\ by default)
Liblary files
DevIL.lib
ILU.lib
ILUT.lib
goes to lib directory (c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\lib\ by default)
DLL files
DevIL.dll
ILU.dll
ILUT.dll
goes to project dorectory (...\Project Folder\Project1\ in your case)
Then i added liblary files to project by right click on project->Properties->Linker->Input->Additional Dependencies (wrote just name of liblaries like ILU.lib)
In my project I just include IL\il.h, IL\ilu.h and IL\ilut.h
I think you may got wrong files by the way...
Just in case you never got this worked out, or anyone else has the same problem (like I did):
I had downloaded the 64-bit version of DevIL for my 64-bit Windows computer, but Microsoft Visual Studio (I was using Express) was the 32-bit version.
I downloaded the 32-bit version of DevIL and it worked!
I had the same problem. Seems like the pre-built binaries are swapped: I could link to the ones designated as non-unicode but they would utterly fail trying to use my non-unicode strings and return unicode strings. Try to build your own binaries from the source or use a previous version.
you should compare the function signatures that you see in your errors with the signatures you get with depends.exe (depedency walker). If they differ there may be a compiler-issue.
You may then try to compile with :
extern "C" {
// put your devils-include directives here ...
}
Nothing garantied of course , just a suggestion.
You may also check the 'Additional Library Directories' property on your 'Linker\General' page to see if (when used) it points to the right directory for your build (if you also added a path to the standard VC lib-directories their may be a conflict ,use either one but not both).
Another suggestion is to create a new project and do it all over again ,you may have made an ever so little mistake.
Good luck !
I had the same problem.
In my case it was problem with code in all devil`s .h files
#ifdef _WIN32
#if (defined(IL_USE_PRAGMA_LIBS)) && (!defined(_IL_BUILD_LIBRARY))
#if defined(_MSC_VER) || defined(__BORLANDC__)
#pragma comment(lib, "%LIBNAME%.lib")
#endif
#endif
#endif
after second #if code was deactivated.
i added #pragma comment(lib, "DevIL.lib") (and 2 more) into my main.h and linker errors dissapeared.
sorry for my bad english =[
I don't know if this question is still active, but since it has no chosen answer, I'll post this. I had what seems like the exact same problem with DevIL version 1.7.8. To fix it, I rolled back the version to 1.7.7 and used #undef _UNICODE before including the headers and #define _UNICODE afterwards. The project compiled without linker errors and worked without a hitch. On 1.7.8, the libraries seem to all be unicode, or at least they don't seem to support ascii very well. However, this may just be some weird compatibility issue with my computer as it does not seem to be a common problem
It might be that you have to declare some preprocessor variable to actually tell the compiler that you are importing symbol; I mean something related to __declspec( dllimport )
I did exactly as what Sarah said about the 32-bit or 64-bit Visual Studio versions. I'm on a 64-bit computer running a 32-bit Visual Studio 2012. I obtained this error when I used the x64 DevIL files. Getting the x86 version helped. Here's the basic steps I took to ensure it does run:
Right-click your project and go to Properties.
Under C/C++ > General, add DevIL's 'include' folder under Additional Include Directories.
Then under Linker > General, add DevIL's 'lib' folder (it should contain: DevIL.lib, ILU.lib and ILUT.lib) to Additional Library Directories. For x64 it may not contain a lib folder, it may be just the DevIL directory itself (for version 1.7.8 it was that case).
Also in Linker > Input, add those .lib file names into Additional Dependencies.
Now that should be all you need to do in the project properties. In the main.cpp you should include the appropriate header files and it should work when you initialize.
Example:
#include "IL/il.h"
#include "IL/ilu.h"
#include "IL/ilut.h"
int main(){
ilInit();
iluInit();
ilutRenderer(ILUT_OPENGL); //these are just to initialize
}