I've been trying to install and properly link bit7z into my C++ code as I have to do a task for my internship which concludes in automatically zipping a certain directory and sending the zip-file out as an email. Right now the email is not interesting to me as I can't even get the base program. I just keep getting the Linker Error 2019 and I don't know what to do anymore. I'll provide as much info as I can.
I use Visual Studio 2019.
My .pro file:
TEMPLATE = app
TARGET = aixLogger
DESTDIR = ./Debug
CONFIG += debug console
DEPENDPATH += .
MOC_DIR += .
OBJECTS_DIR += debug
UI_DIR += GeneratedFiles
RCC_DIR += GeneratedFiles
LIBS += -D:/local/aretz/Programmierung/git-workplace/aixLogger/Dependencies/bit7z/lib -lbit7z
INCLUDEPATH += D:/local/aretz/Programmierung/git-workplace/aixLogger/Dependencies/bit7z/include
include(aixLogger.pri)
My .h
#pragma once
#include <qwidget.h>
#include <qobject.h>
#include <bit7z.hpp>
class AIXLogger : public QWidget
{
Q_OBJECT
public slots:
public:
void CompressDir();
void Execute();
};
My .cpp
#include <QCoreApplication>
#include <string>
#include <iostream>
#include <filesystem>
#include <bit7z.hpp>
#include "main.h"
#include "bitcompressor.hpp"
namespace fs = std::filesystem;
using namespace bit7z;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
std::string path = "C:/Users/aretz/Downloads/test";
for (const auto& entry : fs::directory_iterator(path))
std::cout << entry.path() << std::endl;
//return a.exec();
}
void AIXLogger::CompressDir() {
try {
Bit7zLibrary lib{ L"C:/Program Files/7-Zip/7z.dll" };
//BitCompressor compressor{ lib, BitFormat::Zip };
std::vector< std::wstring > files = { L"aretz/downloads/test/test1.txt", L"aretz/downloads/test/test1.txt" };
//Zip Archiv erstellen
//compressor.compress(files, L"output_archive.zip");
//Directory zippen
//compressor.compressDirectory(L"dir/path/", L"dir_archive.zip");
}
catch (const BitException& ex) {
//irgendwas mit &ex machen
}
}
void AIXLogger::Execute() {
CompressDir();
}
I'm also adding pictures of the properties I changed.
Additional DependenciesAdditional Library DirectoriesAdditional Include Directories
EDIT: Here is the actual Error I'm getting with just the line "Bit7zLibrary lib {L"C:/Program Files/7-Zip/7z.dll" };:
Error LNK2019 unresolved external symbol "public: __thiscall bit7z::Bit7zLibrary::Bit7zLibrary(class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > const &)" (??0Bit7zLibrary#bit7z##QAE#ABV?$basic_string#_WU?$char_traits#_W#std##V?$allocator#_W#2##std###Z) referenced in function "public: void __thiscall AIXLogger::CompressDir(void)" (?CompressDir#AIXLogger##QAEXXZ) aixLogger D:\local\aretz\Programmierung\git-workplace\aixLogger\main.obj 1
Severity Code Description Project File Line Suppression State
Error LNK2019 unresolved external symbol "public: virtual __thiscall bit7z::Bit7zLibrary::~Bit7zLibrary(void)" (??1Bit7zLibrary#bit7z##UAE#XZ) referenced in function "public: void __thiscall AIXLogger::CompressDir(void)" (?CompressDir#AIXLogger##QAEXXZ) aixLogger D:\local\aretz\Programmierung\git-workplace\aixLogger\main.obj 1
The problem you're having is that the linker cannot find the bit7z static library.
By default, the bit7z library is built to bit7z\bin\$(PlatformShortName)\, where $(PlatformShortName) is either x86 or x64 according to your target architecture.
However, you specified a different library directory (bit7z\lib\), which is wrong (unless you changed the directory where you output the built library).
You can fix it by changing the path to $(SolutionDir)Dependencies\bit7z\bin\$(PlatformShortName)\.
Also, please note that, on x86, the default library name is just bit7z.lib, while on x64 is bit7z64.lib.
Related
I'm trying to perform some basic unit tests on a class that's in one project in a solution (Let's call it Project1) in another unit test project (Let's call it UnitTest1) in c++. I'm using the very latest version of visual studio 2019.
I created a brand new solution in visual studio 2019 for c++, and added a console application with a class HelloWorld in another file that just has a method to return a std::string "Hello World".
I then added a new "Native Unit Test Project" to the solution, under references added the Project1 console application, and typed the code as shown below:
The project1 file:
#include <iostream>
#include "HelloWorld.h"
int main() {
HelloWorld* hello = new HelloWorld();
std::cout << hello->sayHello();
}
HelloWorld.h:
#pragma once
#include <string>
class HelloWorld {
public: HelloWorld();
public: std::string sayHello();
};
HelloWorld.cpp:
#include "HelloWorld.h"
#include <string>
HelloWorld::HelloWorld() {
}
std::string HelloWorld::sayHello() {
return std::string("Hello World");
}
UnitTest1.cpp:
#include "pch.h"
#include "CppUnitTest.h"
#include "..//ConsoleApplication1/HelloWorld.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace UnitTest1 {
TEST_CLASS(UnitTest1)
{
public:
TEST_METHOD(TestMethod1)
{
HelloWorld* hello = new HelloWorld();
Assert::AreEqual(hello->sayHello(), std::string("Hello World"));
}
};
}
When i try to run the test via the test explorer, i get:
1>------ Build started: Project: UnitTest1, Configuration: Debug Win32 ------
1>pch.cpp
1>UnitTest1.cpp
1> Creating library C:\Users\Iblob\source\repos\ConsoleApplication1\Debug\UnitTest1.lib and object C:\Users\Iblob\source\repos\ConsoleApplication1\Debug\UnitTest1.exp
1>UnitTest1.obj : error LNK2019: unresolved external symbol "public: __thiscall HelloWorld::HelloWorld(void)" (??0HelloWorld##QAE#XZ) referenced in function "public: void __thiscall UnitTest1::UnitTest1::TestMethod1(void)" (?TestMethod1#UnitTest1#1#QAEXXZ)
1>UnitTest1.obj : error LNK2019: unresolved external symbol "public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall HelloWorld::sayHello(void)" (?sayHello#HelloWorld##QAE?AV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##XZ) referenced in function "public: void __thiscall UnitTest1::UnitTest1::TestMethod1(void)" (?TestMethod1#UnitTest1#1#QAEXXZ)
1>C:\Users\Iblob\source\repos\ConsoleApplication1\Debug\UnitTest1.dll : fatal error LNK1120: 2 unresolved externals
1>Done building project "UnitTest1.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 1 up-to-date, 0 skipped ==========
I would have hoped that the linker should be able to find the files referenced according to microsofts own tutorial on this: https://learn.microsoft.com/en-us/visualstudio/test/writing-unit-tests-for-c-cpp?view=vs-2019
I've tried adding the classes header and cpp as an existing item to my unit test project, but then it just tries to find #include "pch.h" in the HelloWorld class when i try to run the tests.
What am i missing here to tell linker where to find the classes symbols?
Adding #include "..//ConsoleApplication1/HelloWorld.cpp" to my unitTest1.cpp file seems to have fixed things, although i'm not sure if this is an ideal solution, still, will mark as answer.
I seem to have some issues with creating new files for my project.
The issue is that in my sk_error.h file it seems to complain about unresolved external symbols (full error report below). When I place my OutOfRange class in my sk_interface.h file no one complains but when I put the class in the errors file it has issues with it.
If I was to comment out OutOfRange it works perfectly fine so I dont think that it is an issue with the DLL setup.
sk_error.h
#include <sk_platform.h>
#include <sk_interface.h>
namespace sky {
class SK_API OutOfRange : IError {
public:
OutOfRange() {
m_message = " Out Of Range";
m_value = (0 << 1);
}
std::string getMessage() override {
return m_message;
}
};
}
sk_platform.h
#if defined (SK_NONCLIENT_BUILD)
#ifndef SK_API
#define SK_API __declspec(dllexport)
#endif
#else
#ifndef SK_API
#define SK_API __declspec(dllimport)
#endif
#endif
sk_interface.h
#include <sk_platform.h>
#include <string>
namespace sky {
...
class SK_API IError {
public:
virtual std::string getMessage() = 0;
protected:
uint32_t m_value = 0;
std::string m_message = "Error not initialized";
};
}
The Client Project using the DLL
#include <sk_logmanager.h>
#include <sk_error.h>
#include <iostream>
int main() {
sky::g_LogManager.startup();
sky::OutOfRange err;
std::cout << err.getMessage() << "\n";
sky::g_LogManager.shutdown();
while (1) {}
}
Error Output
1>------ Build started: Project: SkyTest, Configuration: Debug Win32 ------
1>main.cpp
1>main.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall sky::OutOfRange::OutOfRange(void)" (__imp_??0OutOfRange#sky##QAE#XZ) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: virtual class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall sky::OutOfRange::getMessage(void)" (__imp_?getMessage#OutOfRange#sky##UAE?AV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##XZ) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall sky::OutOfRange::~OutOfRange(void)" (__imp_??1OutOfRange#sky##QAE#XZ) referenced in function _main
1>C:\Users\Matt\Documents\Game Development\DevEnv\SkyTest\Debug\SkyTest.exe : fatal error LNK1120: 3 unresolved externals
1>Done building project "SkyTest.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Edit:
I am using Visual Studio 2017 (could be the source of the error). The Client Project is using the .lib file.
An unresolved external is always a link error. It even has it in its name: LNK2019.
It is telling you it cannot find the implementation for sky::OutOfRange::OutOfRange()
You have it in a header somewhere and you've called it, but you have not linked to the library that implements it.
We have no way of telling you what library implements it or where it lives on your hard drive. You will have to consult the documentation for OutOfRange, the author of it, or yourself.
I can tell you that you will want to check:
right click the executable project->
properties->linker->general->additional library directories
properties->linker->input->additional dependencies
and make sure the path to the library that defines OutOfRange is in the former and the library name is in the latter.
EDIT: If the library itself has a header that imports it, as it appears from the code you posted, you just need to set up the additional directories part.
In the end, you have to consult the documentation for whatever library you are using or hit up their forums.
I am not sure but this may be related to your solution configuration and solution platform. It wasn't working for me, when I set my solution configuration to "Debug" and platform to "x64"; it started working after setting it to Release - x86
I'm trying to compile some relatively simple code in Qt C++ but I'm getting the following linker error and can't figure out what the issue is.
main.obj:-1: erreur : LNK2019: unresolved external symbol
"class QUuid __cdecl uuid::fromString(class QString const &)"
(?fromString#uuid##YA?AVQUuid##ABVQString###Z) referenced in function _main
Other files compiles fine but somehow these two (uuid.h/uuid.cpp) have this error.
Also if that's relevant, if I right-click on "uuid.cpp" in Qt Editor and select "Compile", I get this error, which also doesn't happen for other cpp files:
Start : "C:\Qt\Tools\QtCreator\bin\jom.exe" -f Makefile.Debug debug/uuid.obj
Error: Target debug/uuid.obj doesn't exist.
Any idea what the issue could be?
uuid.h
#ifndef UUID_H
#define UUID_H
#include <stable.h>
namespace uuid {
QUuid fromString(const QString& s);
}
#endif // UUID_H
uuid.cpp
#include <stable.h>
#include "uuid.h"
namespace uuid {
QUuid fromString(const QString& s) {
// ....
}
}
main.cpp
#include <stable.h>
#include "uuid.h"
int main(int argc, char *argv[]) {
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QUuid test = uuid::fromString("f601c97e494a46a7b393bb0366e679a1");
return app.exec();
}
Removing the build folder, and in particular the make files, fixed the issue. Running the Clean command from Qt Creator was not enough.
I am trying to create a rather simple project in native c++ that calls a a managed dll.
this how my native c++ code looks:
// MyCppStud.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "MyStudWrapper\MyStudentWrapperWrapper.h"
int _tmain(int argc, _TCHAR* argv[])
{
char * path = "C:/Users/rami.schreiber/documents/visual studio 2013/Projects/TestProj/test.xml";
MyStudentWrapperWrapper* student = new MyStudentWrapperWrapper();
// student->GetStudent(path);
return 0;
}
and here are the .h and .cpp files for the managed dll (compiled with /clr)
//MyStudentWrapperWrapper.h
#pragma once
//#ifdef THISDLL_EXPORTS
#define THISDLL_API __declspec(dllexport)
/*#else
#define THISDLL_API __declspec(dllimport)
#endif*/
class MyStudentWrapper;
class THISDLL_API MyStudentWrapperWrapper
{
private:
MyStudentWrapper* _Impl;
public:
MyStudentWrapperWrapper();
MyStudentWrapperWrapper(MyStudentWrapper* student);
~MyStudentWrapperWrapper();
MyStudentWrapperWrapper* GetStudent(const char* path);
void SaveStudent(MyStudentWrapperWrapper* student, const char* path);
};
// MyStudentWrapperWrapper.cpp
#pragma once
#include "stdafx.h"
#include "MyStudWrapper.h"
#include "MyStudentWrapperWrapper.h"
MyStudentWrapperWrapper::MyStudentWrapperWrapper()
{
_Impl = new MyStudentWrapper;
}
when i build the solution i get a link error
1>MyCppStud.obj : error LNK2019: unresolved external symbol "public: __thiscall MyStudentWrapperWrapper::MyStudentWrapperWrapper(void)" (??0MyStudentWrapperWrapper##QAE#XZ) referenced in function _main
1>c:\users\...\documents\visual studio 2013\Projects\MyStudentProj\Debug\MyCppStud.exe : fatal error LNK1120: 1 unresolved externals
From what I understand I am not referencing the the .lib file correctly and therefor the linker does not recognize the c'tor for my wrapper class.
can someone please explain how to correctly reference the dll to my c++ project.
thank you very much!
Basically I am following the basic example here. My .pro file contains QT += core network qtestlib. [Solved] testlib instead of typo qtestlib
When I include QVERIFY, It get the following linker error:
testwaypointlist.obj:-1: error: LNK2019: unresolved external symbol "bool __cdecl
QTest::qVerify(bool,char const *,char const *,char const *,int)"
(?qVerify#QTest##YA_N_NPBD11H#Z) referenced in function "private: void __thiscall
TestWaypointList::fillWaypoints(void)" (?fillWaypoints#TestWaypointList##AAEXXZ)
What files do I miss to link? Without QVERIFY the linker error disappears.
Header file:
#include <QObject>
#include <QtTest/QtTest>
#include "waypointlist.h"
//
// Testing the waypoint list
//
class TestWaypointList : public QObject
{
Q_OBJECT
private:
WaypointList _waypointList;
public:
explicit TestWaypointList(QObject *parent = 0);
private slots:
void fillWaypoints();
};
cpp:
//
// Fill the waypoint list
//
void TestWaypointList::fillWaypoints()
{
_waypointList = WaypointList();
.....
for (int i=0; i < TESTWPLISTCOUNT; i++) {
.....
TestWaypointList::_waypointList.updateOrAppend(id, timeframe);
}
QVERIFY(TestWaypointList::_waypointList.count() == 1); // causing the linker error
}
In your .pro file, you need to change QT += qtestlib to QT += testlib (note the absence of a "q").
Of note, you used to be able to do this: CONFIG += qtestlib, but according to the comment on this page, this is no longer the recommended way of linking to the test library.