During coding in Visual Studio I got an unresolved external symbol error
and I've got no idea what to do. I don't know what's wrong.
Could you please decipher me? Where should I be looking for what kind of errors?
1>Form.obj : error LNK2019: unresolved external symbol "public: class Field * __thiscall Field::addField(class Field *)" (?addField#Field##QAEPAV1#PAV1##Z) referenced in function "public: void __thiscall Form::parse(class std::basic_stringstream<char,struct std::char_traits<char>,class std::allocator<char> > &)" (?parse#Form##QAEXAAV?$basic_stringstream#DU?$char_traits#D#std##V?$allocator#D#2##std###Z)
1>Form.obj : error LNK2019: unresolved external symbol "public: virtual void __thiscall Field::parse(class std::basic_stringstream<char,struct std::char_traits<char>,class std::allocator<char> > &)" (?parse#Field##UAEXAAV?$basic_stringstream#DU?$char_traits#D#std##V?$allocator#D#2##std###Z) referenced in function "public: __thiscall InputField::InputField(class std::basic_stringstream<char,struct std::char_traits<char>,class std::allocator<char> > &)" (??0InputField##QAE#AAV?$basic_stringstream#DU?$char_traits#D#std##V?$allocator#D#2##std###Z)
1>Form.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Field::prompt(void)" (?prompt#Field##UAEXXZ)
1>Form.obj : error LNK2001: unresolved external symbol "public: virtual class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall Field::getName(void)" (?getName#Field##UAE?AV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##XZ)
1>Form.obj : error LNK2001: unresolved external symbol "public: virtual class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall Field::getType(void)" (?getType#Field##UAE?AV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##XZ)
1>Form.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Field::describe(void)" (?describe#Field##UAEXXZ)
1>C:\Users\tomy\Documents\Visual Studio 2010\Projects\zapoctovkac++\Debug\zapoctovkac++.exe : fatal error LNK1120: 6 unresolved externals
This error often means that some function has a declaration, but not a definition.
Example:
// A.hpp
class A
{
public:
void myFunc(); // Function declaration
};
// A.cpp
// Function definition
void A::myFunc()
{
// do stuff
}
In your case, the definition cannot be found. The issue could be that you are including a header file, which brings in some function declarations, but you either:
do not define the functions in your cpp file (if you wrote this code yourself)
do not include the lib/dll file that contains the definitions
A common mistake is that you define a function as a standalone and forget the class selector, e.g. A::, in your .cpp file:
Wrong: void myFunc() { /* do stuff */ }
Right: void A::myFunc() { /* do stuff */ }
Check you are including all the source files within your solution that you are referencing.
If you are not including the source file (and thus the implementation) for the class Field in your project it won't be built and you will be unable to link during compilation.
Alternatively, perhaps you are using a static or dynamic library and have forgotten to tell the linker about the .libs?
It looks to be missing a library or include, you can try to figure out what class of your library that have getName, getType etc ... and put that in the header file or using #include.
Also if these happen to be from an external library, make sure you reference to them on your project file. For example, if this class belongs to an abc.lib then in your Visual Studio
Click on Project Properties.
Go to Configuration Properties, C/C++,
Generate, verify you point to the abc.lib location under Additional
Include Directories. Under Linker, Input, make sure you have the
abc.lib under Additional Dependencies.
I've just seen the problem I can't call a function from main in .cpp file, correctly declared in .h file and defined in .c file. Encountered a linker error. Meanwhile I can call function from usual .c file. Possibly it depends on call convention. Solution was to add following preproc lines in every .h file:
#ifdef __cplusplus
extern "C"
{
#endif
and these in the end
#ifdef __cplusplus
}
#endif
I had an error where my project was compiled as x64 project. and I've used a Library that was compiled as x86.
I've recompiled the library as x64 and it solved it.
sometimes if a new header file is added, and this error starts coming due to that, you need to add library as well to get rid of unresolved external symbol.
for example:
#include WtsApi32.h
will need:
#pragma comment(lib, "Wtsapi32.lib")
I had the same link errors, but from a test project which was referencing another dll. Found out that after adding _declspec(dllexport) in front of each function which was specified in the error message, the link was working well.
Yet another possible problem (that I just scratched my head about for some time):
If you define your functions as inline, they—of course!—have to be defined in the header (or an inline file), not a cpp.
In my case, they were in an inline file, but only because they were a platform specific implementation, and a cpp included this corresponding inl file… instead of a header. Yeah, s**t happens.
I thought I'd leave this here, too, maybe someone else runs into the same issue and finds it here.
This error can be caused by putting the function definitions for a template class in a separate .cpp file. For a template class, the member functions have to be declared in the header file. You can resolve the issue by defining the member functions inline or right after the class definition in the .h file.
For example, instead of putting the function definitions in a .cpp file like for other classes, you could define them inline like this:
template<typename T>
MyClassName {
void someFunction() {
// Do something
...
}
void anotherFunction() {
// Do something else
...
}
}
Or you could define them after the class definition but in the same file, like this:
template<typename T>
MyClassName {
void someFunction();
void anotherFunction();
}
void MyClassName::someFunction() {
// Do something
...
}
void MyClassName::anotherFunction() {
// Do something else
...
}
I just thought I'd share that since no one else seems to have mentioned template classes. This was the cause of the error in my case.
In addition to the excellent answer by Chris Morris above, I found a very interesting way you can receive this same fault if you are calling to a virtual method that hasn't been set to pure but doesn't its own implementation. It is the exact same reason (the compiler can't find an implementation of the method and therefore crooks), but my IDE did not catch this fault in the least bit.
for example, the following code would get a compilation error with the same error message:
//code testing an interface
class test
{
void myFunc();
}
//define an interface
class IamInterface
{
virtual void myFunc();
}
//implementation of the interface
class IamConcreteImpl
{
void myFunc()
{
1+1=2;
}
}
However, changing IamInterface myFunc() to be a pure virtual method (a method that "must" be implemented, that than a virtual method which is a method the "can" be overridden) will eliminate the compilation error.
//define an interface
class IamInterface
{
virtual void myFunc() = 0;
}
Hopes this helps the next StackOverFlow person stepping through code!
I believe most of the points regarding the causes and remedies have been covered by all contributors in this thread. I just want to point out for my 'unresolved external' problem, it was caused by a datatype defined as macro that gets substituted differently than expected, which results in that incorrect type being supplied to the function in question, and since the function with type is never defined, it couldn't have been resolved. In particular, under C/C++ -> Language, there is an attribute called 'Treat WChar_t As Built in Type, which should have been defined as 'No (/Zc:wchar_t-)' but did not in my case.
I just had a hard time with this. Everything was logically set up. I declared a constructor but didn't define it
class SomeClass
{
SomeClass(); // needs the SomeClass::SomeClass(){} function defined somewhere, even here
}
I almost banged my head on my keyboard when I forgot something so elementary.
See Linker Tools Error LNK2019 at MSDN, it has a detailed list of common problems that cause LNK2019.
Make sure you decorate your header files with
#ifndef YOUR_HEADER_H
#define YOUR_HEADER_H
// your header code here
#endif
Bad things -including this- can happen if you don't
I'm doing some C++ for the first time in a long time, and I'm getting this error when I forget to add the ClassName:: prefix for the function definition, since this is a little unique to C++. So remember to check for that too!
POINTERS
I had this problem and solved it by using pointer. I see that this wasn't your issue but I thought I'd mention it because I sure wish it had been here when I saw this an hour ago. My issue was about declaring a static member variable without defining it (the definition needed to come after some other set ups) and of course a pointer doesn't need a definition. Equally elementary mistake :P
One possible cause of this linker error can also be inline functions that are declared but not defined in a header file that is then included somewhere else. Inline functions have to be defined in every translation unit they are used in.
Make sure that you are not trying to overload the insertion or extraction operators as inline functions. I had this problem and it only went away when i removed that keyword.
What had caused it in my case:
I had a huge file Foo.cpp without a Foo.h. Foo.cpp began like this:
// ... 100 LOC here ...
namespace NS {
// ... 100 more LOC here ...
static int var;
I removed the "static" keyword and added a Foo.h with this:
extern int var;
Do you see the mistake?
I totally missed that var was originally defined in a namespace, because the namespace declaration was buried in other code. The fix is to change the extern like this:
namespace NS {
extern int var;
}
In my case, I needed add the function name to the DEF file.
LIBRARY DEMO
EXPORTS
ExistingFunction #1
MyNewFunction #2
My issue was a sconscript did not have the cpp file defined in it. This can be very confusing because Visual Studio has the cpp file in the project but something else entirely is building.
My issue was: I had to do forward declaration of the class whose ctor was "unresolved external".
In the file where I got the error, I had to put something like this:
#include "ClassB"
class ClassB; // this solved the problem
class ClassA{
void foo(){
ClassB* tmp = new ClassB();
// ...
}
};
Of course, my project is much more complicated and this is just a snippet example. Also when using namespaces, declare them as well.
Just spent a couple of hours to find that the issue was my main file had extension .c instead of .cpp
:/
Yet another possibility to check, it was my problem this time.
I had added the function to the library, and included the library's output folder in the search path.
But I also had a folder with an older version of the library listed before, so VS was using the old library, and of course not finding the new function.
A possible reason for the "Unresolved external symbol" error can be the function calling convention.
Make sure that all the source files are using same standard (.c or .cpp), or specify the calling convention.
Otherwise, if one file is a C file (source.c) and another file is a .cpp file, and they link to the same header, then the "unresolved external symbol" error will be thrown, because the function is first defined as a C cdecl function, but then C++ file using the same header will look for a C++ function.
To avoid the "Unresolved external symbol error", make sure that the function calling convention is kept the same among the files using it.
I came here looking for a possible explanation before taking a closer look at the lines preceding the linker error. It turned out to have been an additional executable for which the global declaration was missing!
I faced a similar issue and finally managed to solve it by adding __declspec(dllimport) to the declaration of the class:
// A.hpp
class __declspec(dllimport) A
{
public: void myFunc();
// Function declaration
};
In my case I had multiple namespaces in my header file without nesting (one after the other) however in my source file I had accidentally nested one of the namespaces inside another:
// myExample.h
#ifndef MYEXAMPLE_H
#define MYEXAMPLE_H
namespace A
{
void aFunc();
}
namespace B
{
void bFunc();
}
// myExample.cpp
#include "myExample.h"
namespace A
{
void aFunc()
{
...
}
namespace B // whoops! I nested this inside namespace A when I didn't mean to.
{
void bFunc()
{
...
}
}
}
// main.cpp
#include "myExample.h"
int main()
{
myExample::B::bFunc();
return 0;
}
When I used F12 to "Go to definition" on the function in Main, Visual Studio found the code in the source file even though it was declared in a deeper namespace by accident.
Debugging Technique
I spotted the issue when renaming the function while trying to debug the issue. The rename preview window showed an "External References" node with the function inside the source file clearly nested under another namespace by accident.
I had the same issue. Mine was working one day and then not the next day after I pulled the latest code.
The latest code did not include the project I was referencing in my library. So when I rebuilt my library, it deleted that .obj file, whoopsy.....
I reincluded the project I needed, built my library, then rebuilt my project that was failing and it worked fine.
Moral of the story, verify your .obj file is where you are referencing it before diving too deep into the rabit hole.
I have had an issue with the same error within my project which I have managed to resolved.
The problem led me here but I found it to be a build file problem within visual studio itself.
If you cannot find anything wrong with your code and your doing all of the above I would recommend looking in the yourProject.vcxproj file and check that it is including your MyClass.cpp and source files as
SynthProject.vcxproj
<ItemGroup>
<ClCompile Include="main.cpp" />
<ClCompile Include="myClass.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="myClass.h" />
</ItemGroup>
SynthProject.vcxproj.filters
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="myClass.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="myClass.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
and not as
SynthProject.vcxproj
<ItemGroup>
<ClCompile Include="main.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="myClass.h" />
<ClInclude Include="myClass.cpp" />
</ItemGroup>
SynthProject.vcxproj.filters
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="myClass.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="myClass.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="myClass.cpp">
<Filter>Source Files</Filter>
</ClInclude>
</ItemGroup>
I have managed to do this manually but would recommend unloading and adding the file back into the project if you do not have, or not using git.
Related
I currently build a purely static library MainLib for our customers that contains all symbols so that they can intrgrate it into their program. For several reasons, I now need to deliver a DLL version of MainLib that contains parts of the symbols alongside a static library FeatureLib that contains the remaining symbols. One reason is that we want to avoid bad guys using our software by simply stealing the DLL that is provided via the program of our customer. This wouldn't work if parts of the symbols are integrated within the calling software via a static library. The user of the package shall only be able to use the DLL if he added the symbols of FeatureLib into his application.
For Linux, I can make this work like a charm,i.e. the symbol doFeature() is not within libMainLib.so, but I don't succeed on this for Windows.
CMakeLists.txt:
cmake_minimum_required(VERSION 3.0)
project(MainLib)
add_library(FeatureLib STATIC src/FeatureLib.c)
target_include_directories(FeatureLib PUBLIC include
PRIVATE src)
add_library(MainLib SHARED src/MainLib.c)
target_include_directories(MainLib PUBLIC include
PRIVATE src)
# I don't want to include symbols from FeatureLib into shared MainLib
#target_link_libraries(MainLib PRIVATE FeatureLib)
add_executable(MainLibDemo src/demo.c)
target_link_libraries(MainLibDemo MainLib FeatureLib) #resolve symbol doFeature()
FeatureLib.h:
extern int doFeature(int input);
MainLib.h:
extern __declspec(dllexport) int MainLib(int input);
FeatureLib.c:
#include "FeatureLib.h"
int doFeature(int input) {return 4;}
MainLib.c:
#include "FeatureLib.h"
#include "MainLib.h"
__declspec(dllexport) int MainLib(int input)
{
if (input > 2) {
return doFeature(input);
} else {
return doFeature(0);
}
}
demo.c:
#include <stdio.h>
#include <stdlib.h>
#include "MainLib.h"
int main(int argc, char **argv)
{
if(argc > 1)
return MainLib(atoi(argv[1]));
else
return 0;
}
With this, I get the following compilation error:
"C:\Daten\tmp\DemoProject\simple\build\ALL_BUILD.vcxproj" (Standardziel) (1) ->
"C:\Daten\tmp\DemoProject\simple\build\MainLib.vcxproj" (Standardziel) (4) ->
(Link Ziel) ->
MainLib.obj : error LNK2019: unresolved external symbol _doFeature referenced in function _MainLib [C:\Daten\tmp\DemoProject\simple\build\MainLib.vcxproj]
C:\Daten\tmp\DemoProject\simple\build\Debug\MainLib.dll : fatal error LNK1120: 1 unresolved externals [C:\Daten\tmp\DemoProject\simple\build\MainLib.vcxproj]
0 Warnung(en)
2 Fehler
Is this even possible with Windows? What do I have to do to make it work and how can I verify it other than not linking FeatureLib to MainLibDemo. Any ideas are very welcome.
Kind regards,
Florian
The way you do it under Linux will not work under Windows
because dynamic linking works differently here.
Here is one strategy that could work.
In MainLib.dll code, instead of directly calling doFeature
you need to define a global pointer variable of proper function
pointer type and use it to call the function.
This will allow to build MainLib.dll without errors.
Now you need to set this pointer variable. One way would be:
Add exported function to MainLib.dll that takes pointers
to all functions that the DLL needs from the executable.
In FeatureLib.lib code add an initialisation function
that the application will need to call before using
your DLL which will pass pointers to its peers to the DLL.
This is basically the way most programs with plugins use to
give the plugins access to their facilities.
Another way would be to (Warning! I have not tested this specific
solution):
Declare the functions in FeatureLib.lib as exported
with __declspec(dllexport). This way they will be exported
from executable.
In MainLib.dll before first using the pointers use
GetModuleHandle and GetProcAddress to obtain the pointers.
It would best be done in some initialisation function for the
library. Otherwise you need to take care to avoid race conditions.
Hope this will help.
Though I do not think your copy protection scheme will work.
Andrew Henle is right in his comment: it is not hard
to extract the needed code from one executable and include it
in another.
Just to be clear - I have searched the depths of the internet and back for information on how to do this
I'm looking for assistance setting up pthread_Win32 to work with Visual Studio 2005. I'm programming in C, and I have a number of multithreaded assignments to write using pthread.h. However, since pthread is native to unix, I have to write all of my code, ftp it, and then ssh to my class' remote unix system to run it. It makes development take so much longer, and it's incredibly inefficient. I'd love (more than anything) to be able to get this working on my win32 machine, so I can develop in visual studio as I've been doing for quite some time.
I've installed the pthread.lib file and pthread.h file into the respective lib/header directories, where all of the other files are. The DLL on the other hand (the actual library), I've placed in c:\windows\system32. I've tried to add the DLL as a dependency (right click project -> references -> Add new reference), but as others have stated, all I get is a blank dialogue box with no option to add any DLL files or anything. It seems to recognize the header file, but I get these errors when I compile:
1>Linking...
1>main.obj : error LNK2019: unresolved external symbol _imp_pthread_join referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol _imp_pthread_create referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol _imp_pthread_exit referenced in function _fcount
From my research, I've determined that this is a problem with the DLL, and I'm assuming it can't find the definitions of the functions I've referenced in my code. I've searched high and low and I can't seem to figure out any way to overcome this problem. I've added the directories of the lib/header files to my linker, just in-case, but that didn't solve the issue. I need to do something, in visual studio, to specify that I need pthreadVC2.dll as a project dependency - and it seems to be impossible (and extremely frustrating) at this point.
Any words of wisdom?
Thank you very much
I have been through this problem recently.
It appears that the __imp__ prefix is prepended to the function name in case pthread.h is included in dynamic linking mode.
Simply add the PTW32_STATIC_LIB define to your project or your source code before including pthread.h should solve the issue.
#define PTW32_STATIC_LIB
#include <pthread.h>
Although, I am not completely over as Visual Studio now trys to link with the _[FuncName] instead of [FuncName]
In visual studio, function seems to be declared differently wether you are going to link them statically (.lib) or dynamically (.dll).
To define a function you will link dynamically :
__declspec (dllimport) int myFunc(int myArgs) ;
To define function you are exporting for dynamic linking :
__declspec (dllexport) int myFunc(int myArgs) ;
And the simpliest, to define a function you will link statically:
int myFunc(int myArgs) ;
[EDIT]
I am going on my investigations and went through this on MS help center.
It seems that to avoid the _[FuncName] effect it is required to define a static linked library function by the following:
int __cdecl myFunc(int MyArgs) ;
Have you added pthreadVC.lib (or whichever particular lib you need) to the project property:
Linker/Input/Additional Dependencies
It's not enough to just have the lib file in a particular directory, the linker needs to be told to use it as an input.
Just adding pthreadVC2.lib to linker list is not suffiecient.
You also have to add addtional lib like pthreadVCE2.lib and pthreadVSE2.lib.
I am facing same issue but then I resolved it through adding these files.
This question is raised due to a situation that I encountered
Say I have these external files and some declarations or definitions in them:
foo1.h
extern void ext_func();
foo1.c
void ext_func(){
....
}
foo2.c
#include "foo1.h"
int Modelica_func(){
ext_func();
}
I defined ext_func() in foo1.c. Then, in foo1.h I declared it to be extern, because I want to use it in foo2.c. Modelica_func() is the function that I will be using in Modelica.
The compiler always throws out error LNK2019 to me complaining unresolved external symbol, I guess it's probably due to the reason that the header file cannot find it's matching c file. I am working in Dymola, and I've put all of these files in WorkingFolder/Sources/Include. But still I got the same error. I want others to see my code, so I cannot use static or dynamic library.
Greatly appreciated if anyone could help me a bit of this. THANKS!
You can find some details in Section 12.9.4 of the Modelica Specification.
Just to be clear - I have searched the depths of the internet and back for information on how to do this
I'm looking for assistance setting up pthread_Win32 to work with Visual Studio 2005. I'm programming in C, and I have a number of multithreaded assignments to write using pthread.h. However, since pthread is native to unix, I have to write all of my code, ftp it, and then ssh to my class' remote unix system to run it. It makes development take so much longer, and it's incredibly inefficient. I'd love (more than anything) to be able to get this working on my win32 machine, so I can develop in visual studio as I've been doing for quite some time.
I've installed the pthread.lib file and pthread.h file into the respective lib/header directories, where all of the other files are. The DLL on the other hand (the actual library), I've placed in c:\windows\system32. I've tried to add the DLL as a dependency (right click project -> references -> Add new reference), but as others have stated, all I get is a blank dialogue box with no option to add any DLL files or anything. It seems to recognize the header file, but I get these errors when I compile:
1>Linking...
1>main.obj : error LNK2019: unresolved external symbol _imp_pthread_join referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol _imp_pthread_create referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol _imp_pthread_exit referenced in function _fcount
From my research, I've determined that this is a problem with the DLL, and I'm assuming it can't find the definitions of the functions I've referenced in my code. I've searched high and low and I can't seem to figure out any way to overcome this problem. I've added the directories of the lib/header files to my linker, just in-case, but that didn't solve the issue. I need to do something, in visual studio, to specify that I need pthreadVC2.dll as a project dependency - and it seems to be impossible (and extremely frustrating) at this point.
Any words of wisdom?
Thank you very much
I have been through this problem recently.
It appears that the __imp__ prefix is prepended to the function name in case pthread.h is included in dynamic linking mode.
Simply add the PTW32_STATIC_LIB define to your project or your source code before including pthread.h should solve the issue.
#define PTW32_STATIC_LIB
#include <pthread.h>
Although, I am not completely over as Visual Studio now trys to link with the _[FuncName] instead of [FuncName]
In visual studio, function seems to be declared differently wether you are going to link them statically (.lib) or dynamically (.dll).
To define a function you will link dynamically :
__declspec (dllimport) int myFunc(int myArgs) ;
To define function you are exporting for dynamic linking :
__declspec (dllexport) int myFunc(int myArgs) ;
And the simpliest, to define a function you will link statically:
int myFunc(int myArgs) ;
[EDIT]
I am going on my investigations and went through this on MS help center.
It seems that to avoid the _[FuncName] effect it is required to define a static linked library function by the following:
int __cdecl myFunc(int MyArgs) ;
Have you added pthreadVC.lib (or whichever particular lib you need) to the project property:
Linker/Input/Additional Dependencies
It's not enough to just have the lib file in a particular directory, the linker needs to be told to use it as an input.
Just adding pthreadVC2.lib to linker list is not suffiecient.
You also have to add addtional lib like pthreadVCE2.lib and pthreadVSE2.lib.
I am facing same issue but then I resolved it through adding these files.
I have a CUDA program that works fine, but that is currently all written in one file. I'd like to split this big file into several smaller ones, in order to make it easier to maintain and navigate.
The new structure is :
foo.cuh
foo.cu
bar.cuh
bar.cu
main.cu
The .cuh header files contain structs and function prototypes, and the .cu files contain the function definitions (as usual). The main file includes bar.cuh, and bar.cu includes foo.cuh. All the .cu files include cutil_inline.h, in order to be able to use the CUDA functions.
Hence :
// main.cu
#include "bar.cuh"
#include <cutil_inline.h>
int main() [...]
// bar.cu
#include "bar.cuh"
#include "foo.cuh"
#include <cutil_inline.h>
[...]
// foo.cu
#include "foo.cuh"
#include <cutil_inline.h>
[...]
The problem is that when I compile my Visual Studio 2008 project with this new structure, I get tons of link errors :
error LNK2005: "void __cdecl __cutilBankChecker(unsigned int,unsigned int,unsigned int,unsigned int,unsigned int,unsigned int,char *,int,char *,int)" (?__cutilBankChecker##YAXIIIIIIPADH0H#Z) already defined in cuda_generated_foo.cu.obj cuda_generated_bar.cu.obj
error LNK2005: "void __cdecl __cutilCondition(int,char *,int)" (?__cutilCondition##YAXHPADH#Z) already defined in cuda_generated_foo.cu.obj cuda_generated_bar.cu.obj
error LNK2005: "void __cdecl __cutilExit(int,char * *)" (?__cutilExit##YAXHPAPAD#Z) already defined in cuda_generated_foo.cu.obj cuda_generated_bar.cu.obj
error LNK2005: "int __cdecl cutGetMaxGflopsDeviceId(void)" (?cutGetMaxGflopsDeviceId##YAHXZ) already defined in cuda_generated_foo.cu.obj cuda_generated_bar.cu.obj
error LNK2005: "void __cdecl __cudaSafeCallNoSync(enum cudaError,char const *,int)" (?__cudaSafeCallNoSync##YAXW4cudaError##PBDH#Z) already defined in cuda_generated_foo.cu.obj cuda_generated_bar.cu.obj
error LNK2005: "void __cdecl __cudaSafeCall(enum cudaError,char const *,int)" (?__cudaSafeCall##YAXW4cudaError##PBDH#Z) already defined in cuda_generated_foo.cu.obj cuda_generated_bar.cu.obj
error LNK2005: "void __cdecl __cudaSafeThreadSync(char const *,int)" (?__cudaSafeThreadSync##YAXPBDH#Z) already defined in cuda_generated_foo.cu.obj cuda_generated_bar.cu.obj
error LNK2005: "void __cdecl __cufftSafeCall(enum cufftResult_t,char const *,int)" (?__cufftSafeCall##YAXW4cufftResult_t##PBDH#Z) already defined in cuda_generated_foo.cu.obj cuda_generated_bar.cu.obj
I understand what they mean (all those symbols already defined are part of cutil_inline.h) but I have to include this header in all files, otherwise it does not compile. What am I doing wrong ?
UPDATE: To clarify the situation :
* with all code in one big file, it compiles, links and runs fine
* with the new structure (several smaller files) and including cutil_inline.h in all .cu files, it compiles correctly but fails during linking
* with the new structure and including cutil_inline.h only in the main file, it fails during compilation, saying that the cutil function are unknown in the files where cutil_inline.h was not included (as expected, but I had to try everything)
- List item
This error also happened in my program. I solved it by adding the keyword inline before __global__ or __device__. Then, the error went away.
Somehow, the functions in cutil_inline.h aren't flagged as "inline" when they are compiled.
If you got this error in a normal non-Cuda C++ project, the answer would simply be that you have function definitions (not just declarations) in the header file and the "inline" keyword in missing.
You might have to generate the corresponding .i files (pre-processor) output to really see what's going on after all macro expansion.
EDIT 1/2/2009
If you can't figure out what's wrong just by reading the .h files, because of some macro expansion obfuscation, here's how you generate the .i file:
In the Visual Studio "Solution
Explorer" window, right-click on the
source file and choose "Properties".
In the properties tree, select
"C/C++", "Preprocessor".
Change the "Generate Preprocessed
File" from "No" to one of the other
options.
Then compile the file. The compiler
will write the preprocessor output
to a file and then stop without
actually compiling. You can see in
the .i file produced what the final
result of all macro expansions is.
You will have to go back and reset
that property back to "No" in order
to get the project to compiler to
work properly again.
Do you need to link with the cutil library (i.e. cutil32D.lib for 32-bit debug etc.)?
For some reason you have multiple definitions. Are you using the NVIDIA Cuda.rules file to enable Visual Studio to compile your .cu files to .obj files? It looks like you have modified the rules to link with cutil, whereas you should use the NVIDIA Cuda.rules to tell VS how to compile .cu to .obj, then modify the standard linker properties to pull in the cutil library.
Consider using 'static' instead of 'inline' to avoid warnings during compilation. That's according to this answer. The causes to this error are discussed here:
However, that's most likely caused by including .cuh files (containing your kernels) into a usual .h file. Either:
make a separate dll filled with your .cuh and .cu files, and link against that;
or rename your .h files to .cuh and .cpp to cu. For this option, make sure to also do this: https://stackoverflow.com/a/20057857/9007125
In the context menu for your .cu file (that you just renamed), select Properties. Then go to General and make sure Item Type is set to CUDA C/C++.
Mind you, the second option will make your project compile a lot slower (compiles 4 times slower)