Microsoft Visual Studio 2008 C++ error LNK2001, Windows Vista 64 bit - c++

I am getting the following linker error when trying to link an application to a "3rd-party library", where I myself build the 3rd-party library in question. Here is the error I get:
error LNK2001: unresolved external symbol "public: static class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
const namesp::classname::VARIABLE" (?VARIABLE#classname#namesp##2V?$basic_string#DU?
$char_traits#D#std##V?$allocator#D#2##std##B) <path\to\mylib>.dll : fatal error LNK1120: 1 unresolved externals
The variable in question is defined in a class which is built as part of the 3rd party library. Here is the snippet of the class header as concerns the variable in question:
namespace namesp {
class MY_EXPORT classname {
public:
static const std::string VARIABLE;
};
}
while the corresponding snippet of the cpp is as follows:
#include <namesp/classname.hpp>
namespace namesp {
const std::string classname::VARIABLE = "VARIABLE";
}
The export symbol is defined in a separate header as follows:
#if defined(WINDOWS) && defined(SHARED)
#if(COND)
#define MY_EXPORT __declspec(dllexport)
#else
#define MY_EXPORT __declspec(dllimport)
#endif
#else
#define MY_EXPORT
#endif
Finally, I am using it in my application cpp as follows, say:
#include <namesp/classname.hpp>
namespace appnamesp {
appclass::somefunc() {
namesp::classname cn; //-Compiles
namesp::anotherclass ac; //-Compiles
ac.func(); //-Compiles
std::string s = namesp::classname::VARIABLE; //-Linker error
other stuff;
}
}
This results in the linker error on Windows 64 bit Vista, MS VS2008. What bothers
me is that
This error is not seen on linux, same application built with RHEL5 gcc4.1.2
Another class defined via same export symb is usable..
What am I doing wrong? Is this something to do with the static keyword, or is it the export symbol? My suspicion is the latter, but then I have another class that doesn't involve static variables that is defined similarly in my 3rd party library and accessed via the same export symbol which does not lead to linker errors, as indicated above.
This confuses me.

Shouldn't __declspec(dllimport) be __declspec(dllexport) ?

I figured out the answer to this.. yes, it is related to what OJ wrote. Basically I was missing a cmake definition that activated a condition that defined a symbol to __declspec(dllexport). Thanks anyway to #OJ for his pointer.

Related

Symbols in lib not being included

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

Error linking PostgreSQL custom C++ project in Visual Studio

I wrote a series of custom C PostgreSQL functions in Notepad++. I used the VS2015 x64 Native Tools command line utility to compile the code and linked it. No problems and worked perfectly.
But as much fun as coding in Notepad++ is, I decided to create a project in Visual Studio. After several hours of getting configurations correct, I can get the project to compile, but not link.
The specific errors are:
Error LNK2019 unresolved external symbol "double __cdecl
DatumGetFloat8(unsigned __int64)" (?DatumGetFloat8##YAN_K#Z)
referenced in function "unsigned __int64 __cdecl wrapf64(struct
FunctionCallInfoData *)"
(?wrapf64##YA_KPEAUFunctionCallInfoData###Z) ...
Error LNK2019 unresolved external symbol "unsigned __int64 __cdecl
Float8GetDatum(double)" (?Float8GetDatum##YA_KN#Z) referenced in
function "unsigned __int64 __cdecl wrapf64(struct FunctionCallInfoData
*)" (?wrapf64##YA_KPEAUFunctionCallInfoData###Z) ...
The symptom appears to be in fmgr.h (comments by me):
/* these macros hide the pass-by-reference-ness of the datatype: */
#define PG_GETARG_FLOAT4(n) DatumGetFloat4(PG_GETARG_DATUM(n)) // missing a definition
#define PG_GETARG_FLOAT8(n) DatumGetFloat8(PG_GETARG_DATUM(n)) // missing a definition
#define PG_GETARG_INT64(n) DatumGetInt64(PG_GETARG_DATUM(n))
Looking in postgres.h we see:
#ifdef USE_FLOAT8_BYVAL
extern float8 DatumGetFloat8(Datum X);
#else
#define DatumGetFloat8(X) (* ((float8 *) DatumGetPointer(X)))
#endif
There is no #define. Adding one doesn't resolve the issue.
By contrast:
#ifdef USE_FLOAT8_BYVAL
#define DatumGetInt64(X) ((int64) GET_8_BYTES(X))
#else
#define DatumGetInt64(X) (* ((int64 *) DatumGetPointer(X)))
#endif
This is the unedited source code of PostgreSQL and it worked from the command line utilities. What's the problem inside VS? Or, should I say, why did it work in the command line linker when the #define is missing?
Any suggestions?
One other question I have is my original code had abs(double ...) but inside VS I have to use fabs(double ...). Is this a C vs C++ point? I couldn't find a clear answer in MSDN.
For anyone else who might have similar issues, the answer is to ensure the source files are C, not C++.

Exposing .lib methods through another DLL

I have the following setup in my solution (all C++):
Project1, compiled as static library (.lib).
Project2, compiled as DLL, includes the .lib generated in 1.
Project3, includes the DLL generated in 2.
Now I want to expose functions of project1 to project3, without directly including the .lib of project 1. I keep having linker errors.
error LNK2001: unresolved external symbol
Project 1 is set up to use dllexport and dllimport in the following way (FOO_API is in front of the classes / methods to expose as well of course):
#if defined(FOO_STATIC)
#define FOO_API
#define FOO_TEMPLATE(type) template class type
#else
#ifdef FOO_EXPORTS
#define FOO_API __declspec(dllexport)
#define FOO_TEMPLATE(type) template class FOO_API type
#else
#define FOO_API __declspec(dllimport)
#define FOO_TEMPLATE(type) extern template class FOO_API type
#endif
#endif
Since we compile Project1 as a static library, the dllexport path won't be taken (we define FOO_STATIC). Via the DLL of Project2 however, I want to expose the methods of Project1. I tried to create a .cpp file in Project2 that defines FOO_EXPORTS and then includes the headers of the files containing the methods I want to export. So:
// somefile_that_will_be_built.cpp
#define FOO_EXPORTS
#include "a.h"
#include "b.h"
#include "c.h"
My hope was that this would trigger the dllexport code in Project1 so it would be included in the DLL of Project2. I hoped that when Project3 included Project1 headers it would go the dllimport path and than the linker would find the required methods. So:
#include "a.h"
class WrapThis:
public:
SomeMethodInA();
Project3 compiles, but during linking the SomeMethodA() is not found. Is my approach not possible? Do I need to write a module definition file in Project2 instead? I would hope to prevent this as we have some name ambiguity, and name mangling does not help either (I know this can be turned off, but I wouldn't want to do this for other reasons).
Any help would be appreciated as my experience in this part of development is limited.
UPDATE
Remaining errors (took 4 as example):
2>Stdafx.obj : error LNK2028: unresolved token (0A000683) "public: void __cdecl fooEx::Load(char const * const)" (? Load#fooEx#Namespace4#Namespace1#Namespace2#Namespace3##$$FQEAAXQEBD#Z) referenced in function "public: void __clrcall Namespace1::Namespace2::Namespace3::Namespace4::FooEx::Load(class System::String ^)" (?Load#FooEx#Namespace4#Namespace1#Namespace2#Namespace3##$$FQE$AAMXPE$AAVString#System###Z)
2>Stdafx.obj : error LNK2028: unresolved token (0A000684) "public: void __cdecl fooEx::LoadHeader(char const * const)" (?LoadHeader#fooEx#Namespace4#Namespace1#Namespace2#Namespace3##$$FQEAAXQEBD#Z) referenced in function "public: void __clrcall Namespace1::Namespace2::Namespace3::Namespace4::FooEx::LoadHeader(class System::String ^)" (?LoadHeader#FooEx#Namespace4#Namespace1#Namespace2#Namespace3##$$FQE$AAMXPE$AAVString#System###Z)
2>Stdafx.obj : error LNK2028: unresolved token (0A000686) "public: void __cdecl fooEx::Save(char const * const,double,double)" (?Save#fooEx#Namespace4#Namespace1#Namespace2#Namespace3##$$FQEAAXQEBDNN#Z) referenced in function "public: void __clrcall Namespace1::Namespace2::Namespace3::Namespace4::FooEx::Save(class System::String ^,double,double)" (?Save#FooEx#Namespace4#Namespace1#Namespace2#Namespace3##$$FQE$AAMXPE$AAVString#System##NN#Z)
2>Stdafx.obj : error LNK2028: unresolved token (0A000687) "public: void __cdecl fooEx::Save(char const * const)" (?Save#fooEx#Namespace4#Namespace1#Namespace2#Namespace3##$$FQEAAXQEBD#Z) referenced in function "public: void __clrcall Namespace1::Namespace2::Namespace3::Namespace4::FooEx::Save(class System::String ^)" (?Save#FooEx#Namespace4#Namespace1#Namespace2#Namespace3##$$FQE$AAMXPE$AAVString#System###Z)
Project1 - classA (compiled with FOO_EXPORT) into static lib.
class FOO_API fooEx : public foo
{
public:
fooEx();
virtual void Free();
void Load(const char filename[]);
void LoadHeader(const char filename[]);
virtual void LoadRawData();
void Save(const char filename[]);
}
May be important:
Project1 uses precompiled headers.
Load & LoadHeader are defined in multiple files in the exact same way (other extensions of foo class).
virtual methods are defined in the base class as well as in the other implementations of that base class.
Project2 - Compiled as DLL. Includes Project1.lib via Linker input, additional dependencies.
Project3 - Compiled as DLL. Example class that has methods that cannot be linked.
This cannot work of course, the .lib code was compiled with the wrong #define in effect. So its functions won't be exported.
You'll either have to rebuild the .lib with FOO_EXPORTS defined or write a .def file that lists the functions that must be exported. Rebuilding is of course by far the least painful solution, you could simply add another configuration to the lib project and include the project in your DLL solution. Or always build the lib with FOO_EXPORTS defined, it is still a static library that can be linked into a non-DLL project.
All the compiled binary code for project1 is contained within the .lib file.
You can't use it from another project without including it at compilation time.
You could redefine the parts of project1 that you wish to share at run time as a shared library (i.e. a DLL).

unresolved external symbol for __declspec(dllimport) when using dll to export class

I want to define a derived class based on a dll exported class. The base class is defined in Project A, and the derived class is in Project B.
Firstly, in Project A, preprocessor MYDLL_BUILD is defined. And I use a header file to specify export/import:
#if !defined(MYDLL_BUILD)
# pragma comment(lib, "myDll.lib")
#endif
#if defined(MYDLL_BUILD)
# define MYDLL_API __declspec(dllexport)
#else
# define MYDLL_API __declspec(dllimport)
#endif
Then I define the base class:
class MYDLL_API DllObject
{
public:
virtual ~DllObject() {}
protected:
DllObject() { m_count = 3; }
private:
int m_count;
};
In Project B, the preprocessor MYDLL_BUILD is not defined. Here is the derived class:
class MyClass : public DllObject
{
public:
~MyClass(){}
MyClass() { m_data = 20; }
private:
int m_data;
};
I have included the dll and lib file, but still I get the unresolved external symbol error:
2>Test_Entry.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: virtual __thiscall ADAI::DllObject::~DllObject(void)" (__imp_??1DllObject#ADAI##UAE#XZ) referenced in function "public: virtual __thiscall MyClass::~MyClass(void)" (??1MyClass##UAE#XZ)
2>Test_Entry.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) protected: __thiscall ADAI::DllObject::DllObject(void)" (__imp_??0DllObject#ADAI##IAE#XZ) referenced in function "public: __thiscall MyClass::MyClass(void)" (??0MyClass##QAE#XZ)
2>c:\Users\Adai\Documents\Visual Studio 2010\Projects\Test_Main\Debug\Test_Main.exe : fatal error LNK1120: 2 unresolved externals
I searched online, most of the answers claim that the lib is missing. But those instructions do not solve my problem.
When I change
class MYDLL_API DllObject
to
class __declspec(dllexport) DllObject
The solution compiles with no error. I really do not understand the reason. Can someone please help? Thanks in advance.
The reason is inlining.
In short, to make inline functions possible C++ must allow the same definition of function to be included and compiled in multiple compilation units (basically .cpp files) without causing errors. Compiler can, but doesn't have to emit code for any of this definitions. Then linker is allowed to chose one copy.
This complicates dll creation because you need to export exactly one copy but compiler doesn't know which copy is the right one. In this case by adding some code to DllObject.cpp you made the compiler emit code for DllObject and linker had some copy of DllObject::~DllObject to export.
I cannot give you more detailed explanation of your particular case because I don't know full source and compilation options for your project.
I had the same issue today. I was including the .dll and .lib files from my version of DllObject, But it wasn't helping.
To fix, What I had to do was add the .lib files name to my MyCLass version's project's Properties->Linker->Input->Additional dependencies.
If this doesn't work, You might want to add the .lib location's directory address in Properties->Linker->General->Additional library directories.

Linker error when trying to link to a dll

I have a Dll Which has 4 files Header files-1.StreamReader.h 2.StreamWriter.h Source Files-StreamReader.cpp 2.StreamWriter.cpp in windows VS2008.
StreamReader.h
Class StreamReader{
public:
static __declspec(dllexport) StreamReader* GetInstance();
//other functions
private:
StreamReader(){}
~StreamReader(){}
static StreamReader *m_pInstance;
};
StreamReader.cpp
StreamReader *StreamReader::m_pInstance=NULL;
StreamReader *StreamReader::GetInstance()
{
return((m_pInstance==NULL)?m_pInstance=new StreamReader:m_PInstance);
}
//other functions
I have a very similar structure for StreamWriter and a GetInstance() there as well.
When I link to this dll statically in a exe it complains during compilation
error LNK2001: unresolved external symbol "private: static class
StreamReader * StreamReader::m_pInstance"
(?m_pInstance#StreamReader##0PAV1#A)
error LNK2019: unresolved
external symbol "public: static class StreamReader * __cdecl
StreamReader::GetInstance(void)"
(?GetInstance#StreamReader##SAPAV1#XZ) referenced in function _main
The exe is also written in c++. But it can find StreamWriter symbol. The StreamWriter and StreamReader files are essentially the same except for the fact that one reads and one writes to a file. What am i missing? Thank you
Make sure the .cpp files are actually in the project and not just in the folder. That way, the compiler knows to compile them and produce the object files that the linker is looking for.
When you import a dll you need to have dllimport declared.
You have
static __declspec(dllexport) StreamReader* GetInstance();
you need
static __declspec(dllimport) StreamReader* GetInstance();
you can use the same header file for this by using a preprocessor definition
#ifdef _EXPORTING
#define CLASS_DECLSPEC __declspec(dllexport)
#else
#define CLASS_DECLSPEC __declspec(dllimport)
#endif
static CLASS_DECLSPEC StreamReader* GetInstance();
make sure to add _EXPORTING preprocessor definition to the project that exports the DLL