Reputation: 8505
I have a library (dll) which exposes a class along with its constructors which are supposed to be used in other modules (exe and dll). I am able to instantiate that class from other library modules but not exe modules. I get the linker error - 'error LNK2019: unresolved external symbol' during linking. I am confused why linking succeeds when used in other library projects and not exe project. Can somebody help me with this?
the following is the class declaration:
class __declspec(dllimport) MyException
{
public:
MyException(unsigned int _line, const char *_file, const char *_function, MyExceptionType _type, const wchar_t* _message = 0, ...);
};
This is the whole error: error LNK2019: unresolved external symbol "__declspec(dllimport) public: __cdecl MyException::MyException(unsigned int,char const *,char const *,enum MyException::MyExceptionType,unsigned short const *,...)" (_imp??0MyException@@QAA@IPBD0W4MyExceptionType@0@PBGZZ) referenced in function "public: __thiscall MyClassUsesMyException::MyClassUsesMyException(class SomeClass *,int)" (??0MyClassUsesMyException@@QAE@PAVSomeClass@@H@Z)
MyClassUsesMyException is being instantiated in 'MyApp.cpp'.
Thanks, Rakesh.
Upvotes: 1
Views: 1313
Reputation: 66194
Update: wchar_t
Not Always Native
After a fairly long exchange of information and getting a little more info from the OP, the problem is essential this:
class __declspec(dllimport) MyException
{
public:
MyException(unsigned int _line,
const char *_file,
const char *_function,
MyExceptionType _type,
const wchar_t* _message = 0, // <<== note wchar_t type
...);
};
Visual C++ can be configured to either treat wchar_t
as a native type or not. When not treated as a native type, unsigned short
is the specified macro substitution for wchar_t
. The linker was complaining about the above function being unresolvable, but what really caught my eye was this at the tail of the undefined symbol:
,unsigned short const *,...)
Note the unsigned short
. This hinted to me that the compiler was using non-native wchar_t
when compiling the EXE. I considered it possible that maybe the DLL was compiled with wchar_t
configured as native, thereby introducing a different signature and thus not matching up at link time.
If you're surprised this was the problem, imagine how surprised Rakesh and I were =P
Original Answer
That class should be in a single common header with preprocessor logic to determine proper import/export state of the declaration. Like so:
MyDLL.h
#ifndef MYDLL_H
#define MYDLL_H
// setup an import/export macro based on whether the
// DLL implementing this class is being compiled or
// a client of the DLL is using it. Only the MyDLL.DLL
// project should define MYDLL_EXPORTS. What it is
// defined as is not relevant. *That* it is defined *is*.
#ifdef MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endif
class MYDLL_API MyException
{
// your class definition here...
};
#endif
Then, in your DLL project that implements the exception (and only in that project), add MYDLL_EXPORTS to the preprocessor defines list in your project configuration.
Upvotes: 0