Whats reason of error: LNK2019 unresolved external symbol "__declspec(dllimport) public: __cdecl NS::A::A
-
//TestDll2.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __cdecl NS::A::A(int (__cdecl*)(class std::basic_string,class std::allocator >))" (__imp_??0A@NS@@QEAA@P6AHV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z@Z) referenced in function main =====file TestDll2.cpp=====
#include
#include "..\\MyDll\\MyDll.h"using namespace std;
using namespace NS;int Print(string str);
int main()
{
NS::A* a = new NS::A(Print);
NS::printDlgt("Hello World!");
}int Print(string str)
{
cout << str << endl;
return 0;
}MyDll project files =====MyDll.cpp=====
#include "pch.h"
#include "MyDll.h"
namespace NS
{
PrintDelegate printDlgt;
A::A(PrintDelegate print_Dlgt)
{
NS::printDlgt = print_Dlgt;
}
}=====MyDll.h=====
#include
#ifndef MYDLL_H
#define MYDLL_H//MYDLL_EXPORTS is set in C++\Preprocessor
#ifdef MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endifusing namespace std;
typedef int (*PrintDelegate)(string str);namespace NS
{
extern PrintDelegate printDlgt;
class MYDLL_API A
{
public:
A(PrintDelegate print_Dlgt);
};
}
#endif -
//TestDll2.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __cdecl NS::A::A(int (__cdecl*)(class std::basic_string,class std::allocator >))" (__imp_??0A@NS@@QEAA@P6AHV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z@Z) referenced in function main =====file TestDll2.cpp=====
#include
#include "..\\MyDll\\MyDll.h"using namespace std;
using namespace NS;int Print(string str);
int main()
{
NS::A* a = new NS::A(Print);
NS::printDlgt("Hello World!");
}int Print(string str)
{
cout << str << endl;
return 0;
}MyDll project files =====MyDll.cpp=====
#include "pch.h"
#include "MyDll.h"
namespace NS
{
PrintDelegate printDlgt;
A::A(PrintDelegate print_Dlgt)
{
NS::printDlgt = print_Dlgt;
}
}=====MyDll.h=====
#include
#ifndef MYDLL_H
#define MYDLL_H//MYDLL_EXPORTS is set in C++\Preprocessor
#ifdef MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endifusing namespace std;
typedef int (*PrintDelegate)(string str);namespace NS
{
extern PrintDelegate printDlgt;
class MYDLL_API A
{
public:
A(PrintDelegate print_Dlgt);
};
}
#endifOscar K. wrote:
//MYDLL_EXPORTS is set in C++\Preprocessor
What do you mean by that?
MYDLL_EXPORTS
should only be defined in MyDll.cpp, just before the#include "MyDll.h"
. You also need to ensure that you add MyDll.lib to the linker options in your build. [edit] On reflection I think maybe the definition ofextern PrintDelegate printDlgt;
is not correct. I think it should also by declared withMYDLL_API
. I will try and test this later today. [/edit] -
Oscar K. wrote:
//MYDLL_EXPORTS is set in C++\Preprocessor
What do you mean by that?
MYDLL_EXPORTS
should only be defined in MyDll.cpp, just before the#include "MyDll.h"
. You also need to ensure that you add MyDll.lib to the linker options in your build. [edit] On reflection I think maybe the definition ofextern PrintDelegate printDlgt;
is not correct. I think it should also by declared withMYDLL_API
. I will try and test this later today. [/edit] -
#define MYDLL_EXPORTS is already set in Debug\Properties\C++\Preprocessor #define MYDLL_EXPORTS in MyDll.cpp invokes macro redefinition extern PrintDelegate printDlgt in MyDll.h is usual decision, that's how it's done
Oscar K. wrote:
#define MYDLL_EXPORTS in MyDll.cpp invokes macro redefinition
You should only have it in one place, and inside the dll implementation file (MyDll.cpp) is the better choice.
Oscar K. wrote:
extern PrintDelegate printDlgt in MyDll.h is usual decision, that's how it's done
Correct, but that only makes it visible to the build of the DLL. When you build your test code the it is declared
extern
which the compiler accepts as it should be defined in another compilation unit, as part of the build of the main program. But when you try to link the program the linker cannot find where that item is actually defined because it only exists in the DLL. And since it has not been exported it is not listed in the lib or exp files. -
Oscar K. wrote:
#define MYDLL_EXPORTS in MyDll.cpp invokes macro redefinition
You should only have it in one place, and inside the dll implementation file (MyDll.cpp) is the better choice.
Oscar K. wrote:
extern PrintDelegate printDlgt in MyDll.h is usual decision, that's how it's done
Correct, but that only makes it visible to the build of the DLL. When you build your test code the it is declared
extern
which the compiler accepts as it should be defined in another compilation unit, as part of the build of the main program. But when you try to link the program the linker cannot find where that item is actually defined because it only exists in the DLL. And since it has not been exported it is not listed in the lib or exp files. -
I added extern PrintDelegate NS::printDlgt; to TestDll2.cpp, but I have got again error unresolved external. I see class A (MyDll.dll) in Dll viewer.
-
And you will continue to get that error until you create the object inside the namespace and use the
MYDLL_API
export prefix. As I have said more than once, you cannot useextern
on an item that only exists in a DLL.