I know similar question has been asked before, but it looks like there is something different in what concerns classes export than a simple function ... I have checked all those solutions, checked all the suggestions but it still looks like I am missing something ...
What's happening:
- I have a master C++ project written in Visual Studio 2013 and I want to add a dll library with various utils. I have created a dummy one, with basically no functionality, but it fails to compile:
2> TestSvc_i.c 2>TestSvc.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall CUtils::CUtils(void)" (__imp_??0CUtils@@QAE@XZ) referenced in function _wWinMain@16 2>C:\Work\TestSvc_root\Debug\TestSvc.exe : fatal error LNK1120: 1 unresolved externals ========== Rebuild All: 1 succeeded, 1 failed, 0 skipped ==========
And the code in the main project looks like this:
extern "C" int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd)
{
CUtils *a = new CUtils();
delete a;
return 1;
}
I have the following setup:
- the master project written in C++ with Visual Studio 2013;
- I am using Unicode charset and the runtime is used in a shared dll;
_UNICODE
is defined;- SubSystem: Windows (
/SUBSYSTEM:WINDOWS
); - I want to create an utility library that should be used in a shared dll. The code looks like this:
Utils.h:
#ifdef UTILS_EXPORTS
#define UTILS_API __declspec(dllexport)
#else
#define UTILS_API __declspec(dllimport)
#endif
// This class is exported from the Utils.dll
class UTILS_API CUtils {
public:
CUtils(void);
};
Utils.cpp:
#include "stdafx.h"
#include "Utils.h"
// This is the constructor of a class that has been exported.
// see Utils.h for the class definition
CUtils::CUtils()
{
return;
}
- I checked the dll-project settings and basically, they're all as in main project;
UTILS_EXPORTS
is defined in dll-project so normally, all definitions should have__declspec(dllexport)
(as expected, not defined inUTILS_EXPORTS
);- I have the following preprocessor definitions:
WIN32
;_DEBUG
;_WINDOWS
;_USRDLL
;UTILS_EXPORTS
; - dll-project is added as a dependency to master-project;
- the dll is copied under
$(SolutionDir)\Debug
but not under$(SolutionDir)\$(MasterProject)\Debug
- I don't know why. I manually copied it, but I still have the same problem; - I ran
DUMPBIN
utility on Utils.dll and here is how it looks:
C:\Work\TestSvc_root\Debug>DUMPBIN /EXPORTS /SYMBOLS Utils.dll Microsoft (R) COFF/PE Dumper Version 10.00.40219.01 Copyright (C) Microsoft Corporation. All rights reserved. Dump of file Utils.dll File Type: DLL Section contains the following exports for Utils.dll 00000000 characteristics 53C632A8 time date stamp Wed Jul 16 10:07:04 2014 0.00 version 1 ordinal base 2 number of functions 2 number of names ordinal hint RVA name 1 0 00011154 ??0CUtils@@QAE@XZ = @ILT+335(??0CUtils@@QAE@XZ) 2 1 000110C8 ??4CUtils@@QAEAAV0@ABV0@@Z = @ILT+195(??4CUtils@@QAEAAV0@ABV0@@Z) Summary 1000 .data 1000 .idata 2000 .rdata 1000 .reloc 1000 .rsrc 4000 .text 10000 .textbss
- I have tried to "sniff" the value of UTILS_API:
#define DO_QUOTE(X) #X #define QUOTE(X) DO_QUOTE(X) #define MY_QUOTED_VAR QUOTE(MYVARIABLE) #pragma message(QUOTE(UTILS_API))
which dumps the correct value: when "used" from dll, it dumps __declspec(dllexport)
, and when used from main-project it dumps __declspec(dllimport)
So, any hint? It looks like there is something that has to do with class export definition/method decoration ... In previous plain old Visual C++ there used to be a "def" file where you could map the exported names ... but in this new version, I am lost.
Thanks!
As a workaround, you may explicitly add .lib file (generated during the build of your .dll) to the list of input libraries in the linker options of the main project.