I'm using a 3rd party COM-based library called Engine in a native WinRT component which should later act as a wrapper for the 3rd party lib.
An Engine.lib and a Engine.h file for the 3rd party lib is setup in my project.
I'm getting the LNK2019 for my following cpp file:
#include "pch.h"
#include "Engine.h"
void Component::Init()
{
ComPtr<IEngine> spEngine;
Settings settings;
CreateEngine(&settings, &spEngine);
}
The code compiles fine and the Engine.lib is setup in the project settings of VS2012. Also does DUMPBIN /EXPORTS for the Engine.lib show that CreateEngine is exposed. I can also use other types defined in the Engine.h, but as soon as CreateEngine is called, a linker error is raised:
Error 1 error LNK2019: unresolved external symbol CreateEngine#8 referenced in function "public: virtual void __cdecl
Engine.h defines CreateEngine like this:
STDAPI CreateEngine(
_In_ Settings * pSettings,
_Outptr_ IEngine **ppEngine );
Where the STDAPI is the usual macro:
#define STDAPI extern "C" HRESULT __stdcall
Any ideas?
Figured it out with the help of Inspired: I was using the lib built for ARM with an x86 build configuration. After changing that it was linking fine.
Related
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
legitmate_relationship.dll : Basically this dll is consumed for one of the unit test project unittest_legitimate_relationship.
As soon as I build unittest_legitimate project, giving some linker errors.
error LNK2019 : unresolved external symbol CheckLr referenced in function "private: bool __cdecl LrTester::LrTest()
here is function defalcation which i am going to call in my unit test project,and which is declared in "legitmate_relationship.h " header file
#ifdef __cplusplus
extern "C"
{
#endif
DLL_IMPORT (bool_t)
CheckLr(STD_HANDLE hPrincipal, STD_HANDLE hCollectionIn, STD_HANDLE hCollectionOut);
#ifdef __cplusplus
}
function is defined like this in file "lrrule.cpp"
DLL_EXPORT (bool_t)
CheckLr(STD_HANDLE hCollectionIn, STD_HANDLE hCollectionOut, STD_HANDLE hPrincipal)
{
}
In order to make use of checklr function in unittest_legitimate project, I have added the .lib file reference in addional dependence . So that the function definition should be available for project.
If I am compiling unittest-legitimate project, I am getting linker errors as mentioned above.
call made to checklr() in lrtest.cpp :
CheckLr((STD_HANDLE)permissionCollectionIn, (STD_HANDLE)permissionCollectionOut, (STD_HANDLE)principal);
I am not sure how to resolve such kind of linker errors.Thanks in advance.
1.Three things to check, the legitimaterelasionship.dll project and unittest_legitimate-relationship.exe project should be the same:
MT/MD
x86/x64
cplusplus/c
2.The legitimaterelasionship.dll project generates a legitimaterelasionship.lib file. The unittest_legitimate-relationship.exe project should link to this legitimaterelasionship.lib file.
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).
I built the google test project.
I added the include directories in General -> Addition Include Directories.
I added the library directory to the Linker -> Additional Library directories
I added gtest_maind.lib and gtestd.lib to Linker -> Input -> Additional Dependencies
I followed instructions in an another chain to change the Code Generation -> Runtime Library to Multi-threaded Debug (/MTd)
Note: I am using Visual Studio 2010
In spite of doing all the above I still get the following link error
Error 1 error LNK2019: unresolved external symbol "public: __thiscall
Utility::~Utility(void)" (??1Utility##QAE#XZ) referenced in function "private: virtual
void __thiscall UtiltyTest_test1_Test::TestBody(void)" (?
TestBody#UtiltyTest_test1_Test##EAEXXZ) C:\Users\<username>\Documents\Visual Studio
2010\Projects\Calc\CalTest\UtilityTest.obj
Am I missing something here. Could someone help me solve this error.
Are you trying to test any .c files?
Because if you are you should try this:
#ifdef __cplusplus
extern "C" {
#endif
void cFunctionCalledFromCppFile();
#ifdef __cplusplus
}
#endif
I want to create unit tests for a Visual C++ project. I tried following these MSDN instructions. I've found pages where they differentiate between unmanaged/mixed/pure code, but I don't fully understand those concepts. My code doesn't use .NET and would likely compile under MinGW with a few code adjustments.
My main project builds an executable, so I followed the steps under To reference exported functions from the test project. For starters I got different project options:
I went with Native Unit Test Project. I added a reference to my main project and I set Include Directories to $(SolutionDir)\Cubes;$(IncludePath). I wrote my code and got this when compiling:
1>Creating library C:\Users\Pieter\Dropbox\Unief\TTUI\TTUIproject\Cubes\Debug\CubesTest.lib and object C:\Users\Pieter\Dropbox\Unief\TTUI\TTUIproject\Cubes\Debug\CubesTest.exp
1>LayoutTest.obj : error LNK2019: unresolved external symbol "public: __thiscall Room::Room(void)" (??0Room##QAE#XZ) referenced in function "public: void __thiscall CubesTest::LayoutTest::NumOfRoomsConsistency(void)" (?NumOfRoomsConsistency#LayoutTest#CubesTest##QAEXXZ)
1>LayoutTest.obj : error LNK2019: unresolved external symbol "public: __thiscall Layout::Layout(class Room *,int)" (??0Layout##QAE#PAVRoom##H#Z) referenced in function "public: void __thiscall CubesTest::LayoutTest::NumOfRoomsConsistency(void)" (?NumOfRoomsConsistency#LayoutTest#CubesTest##QAEXXZ)
1>LayoutTest.obj : error LNK2019: unresolved external symbol "public: void __thiscall Layout::add(int,int,class Room *)" (?add#Layout##QAEXHHPAVRoom###Z) referenced in function "public: void __thiscall CubesTest::LayoutTest::NumOfRoomsConsistency(void)" (?NumOfRoomsConsistency#LayoutTest#CubesTest##QAEXXZ)
1>LayoutTest.obj : error LNK2019: unresolved external symbol "public: void __thiscall Layout::clear(int,int,bool)" (?clear#Layout##QAEXHH_N#Z) referenced in function __catch$?NumOfRoomsConsistency#LayoutTest#CubesTest##QAEXXZ$0
1>C:\Users\Pieter\Dropbox\Unief\TTUI\TTUIproject\Cubes\Debug\CubesTest.dll : fatal error LNK1120: 4 unresolved externals
If I'm not mistaken, this means that the compiler finds the header files, but not the source files. What am I missing?
Here is a step-by-step description on how to add an EXE as an unit-test target.
The key point is to "export" the functions/classes you want to test... You can download the complete sample here: http://blog.kalmbachnet.de/files/CPP_UnitTestApp.zip (I did not change any project settings, so all changes you can see in the source-code; of course, some parts can be made in the project settings).
Create a Win32 Application (Console or MFC or Windows, does not matter); I created a console project called CPP_UnitTestApp:
Add a function you want to test (you can also add classes). For example:
int Plus1(int i)
{
return i+1;
}
Add a header file for the functions you want to test: CPP_UnitTestApp.h
Put the declaration of the methods into the header file, and also export these functions!
#pragma once
#ifdef EXPORT_TEST_FUNCTIONS
#define MY_CPP_UNITTESTAPP_EXPORT __declspec(dllexport)
#else
#define MY_CPP_UNITTESTAPP_EXPORT
#endif
MY_CPP_UNITTESTAPP_EXPORT int Plus1(int i);
Include this header file in the main-cpp (here CPP_UnitTestApp.cpp) and define the EXPORT_TEST_FUNCTIONS before including the header:
#define EXPORT_TEST_FUNCTIONS
#include "CPP_UnitTestApp.h"
Now add a new project (Native unit test project: UnitTest1)
Include the header and the lib to the "unittest1.cpp" file (adopt the paths as you want):
#include "..\CPP_UnitTestApp.h"
#pragma comment(lib, "../Debug/CPP_UnitTestApp.lib")
Go to the project settings of the test project add add a reference to the "UnitTest1" project (Project|Properties|Common Properties|Add New Reference...: Select under "Projects" the "CPP_UnitTestApp"-Project)
Create the unit test function:
TEST_METHOD(TestMethod1)
{
int res = Plus1(12);
Assert::AreEqual(13, res);
}
Run your unit test ;)
As you can see, the main point was to export the function declaration! This is done via __declspec(dllexport) even if it is an EXE.
As I said, the demo project can be downloaded here: http://blog.kalmbachnet.de/files/CPP_UnitTestApp.zip