链接器错误:无法解析构造函数

Linker error: Failing to resolve constructor

本文关键字:构造函数 错误 链接      更新时间:2023-10-16

cpp 的新功能。奇怪的是,我实际上在前一天设法编译了它。但是突然间它今天没有编译,可能是因为一些缓存。一旦我清除了CMake缓存,我就开始收到各种错误......

我定义了一个类,如下所示:

#pragma once
#include <string>
#include <memory>
#include <boost/uuid/uuid.hpp>
#include "lib/Msg.hpp"
#include "lib/SplitParts.hpp"
namespace blz
{
class SmsMsg : Msg
{
public:
enum class SmsCoding { Undefined = -1, SevenBit, EightBit, Ucs2 };
enum class DcsEncodeMode { Undefined = -1, Default, Fx };
enum class Mwi { Undefined = -1, VoiceOn, FaxOn, EmailOn, OtherOn, VoiceOff, FaxOff, EmailOff, OtherOff };
enum class Mclass { Undefined = -1, Zero, One, Two, Three };
SmsMsg(boost::uuids::uuid id, int smsType, std::string& sender, std::string& receiver,
std::string& udhData, std::string& msgData, std::string& smscId, std::string& smscNumber,
std::string& foreignId, std::string& service, std::string& account, int time, Mclass mclass,
Mwi mwi, SmsCoding coding, bool compress, int validity, int deferred, int dlrMask, std::string& dlrUrl,
int pid, int altDocs, int rpi, std::string& charset, std::string& boxId, std::string& binInfo,
int msgLeft, std::unique_ptr<SplitParts> splitParts, int priority, int resendTry, int resendTime,
std::string& metaData);
int encodeDcs(DcsEncodeMode mode);
private:
boost::uuids::uuid id;
int smsType;
std::string sender;
std::string receiver;
std::string udhData;
std::string msgData;
std::string smscId;
std::string smscNumber;
std::string foreignId;
std::string service;
std::string account;
int time;
Mclass mclass;
Mwi mwi;
SmsCoding coding;
bool compress;
int validity;
int deferred;
int dlrMask;
std::string dlrUrl;
int pid;
int altDocs;
int rpi;
std::string charset;
std::string boxId;
std::string binfo;
int msgLeft;
std::unique_ptr<SplitParts> splitParts{};
int priority;
int resendTry;
int resendTime;
std::string metaData;
};
}

该类的实现如下:

#include "SmsMsg.hpp"
inline blz::SmsMsg::SmsMsg(const boost::uuids::uuid id, const int smsType, std::string& sender, std::string& receiver,
std::string& udhData, std::string& msgData, std::string& smscId, std::string& smscNumber,
std::string& foreignId, std::string& service, std::string& account, const int time,
const Mclass mclass, const Mwi mwi, const SmsCoding coding, const bool compress,
const int validity, const int deferred, const int dlrMask, std::string& dlrUrl,
const int pid, const int altDocs, const int rpi, std::string& charset, std::string& boxId,
std::string& binInfo, const int msgLeft, std::unique_ptr<SplitParts> splitParts,
const int priority, const int resendTry, const int resendTime, std::string& metaData) :
id(id),
smsType(smsType),
sender(sender),
receiver(receiver),
udhData(udhData),
msgData(msgData),
smscId(smscId),
smscNumber(smscNumber),
foreignId(foreignId),
service(service),
account(account),
time(time),
mclass(mclass),
mwi(mwi),
coding(coding),
compress(compress),
validity(validity),
deferred(deferred),
dlrMask(dlrMask),
dlrUrl(dlrUrl),
pid(pid),
altDocs(altDocs),
rpi(rpi),
charset(charset),
boxId(boxId),
binfo(binInfo),
msgLeft(msgLeft),
splitParts(std::move(splitParts)),
priority(priority),
resendTry(resendTry),
resendTime(resendTime),
metaData(metaData)
{
}
int blz::SmsMsg::encodeDcs(const DcsEncodeMode mode)
{
auto dcs = 0;
if (coding == SmsCoding::Undefined)
{
coding = udhData.length() ? SmsCoding::EightBit : SmsCoding::SevenBit;
}
if (mwi != Mwi::Undefined)
{
dcs = static_cast<int>(mwi);
if (dcs & 0x04)
{
dcs = (dcs & 0x03) | 0xC0;
}
else
{
dcs = (dcs & 0x03) | 0x08;
dcs |= !msgData.length() ? 0xC0 : coding == SmsCoding::SevenBit ? 0xD0 : 0xE0;
}
}
else
{
if (mode == DcsEncodeMode::Default || mode == DcsEncodeMode::Undefined || coding == SmsCoding::Ucs2 || compress)
{
if (compress)
{
dcs |= 0x20;
}
if (mclass != Mclass::Undefined)
{
dcs |= (0x10 | static_cast<int>(mclass));
}
if (coding != SmsCoding::Undefined)
{
dcs |= (static_cast<int>(coding) << 2);
}
}
else
{
dcs |= 0xF0;
if (coding != SmsCoding::Undefined)
{
dcs |= (static_cast<int>(coding) << 2);
}
dcs |= mclass == Mclass::Undefined ? 1 : static_cast<int>(mclass);
}
}
return dcs;
}

Msg.hpp 和 SplitParts.hpp 只是空类,没有像class Msg {}class SplitParts {}这样的实现。

然后我有一个测试类,例如:

#define CATCH_CONFIG_MAIN
#include "catch.hpp"
#include "SmsMsg.hpp"
#include "lib/SplitParts.hpp"
blz::SmsMsg getTestSms()
{
auto msgId = boost::uuids::uuid();
auto smsType = 1;
std::string sender = "blz";
std::string receiver = "48765432";
std::string udhData = "udhData";
std::string msgData = "Hello Foo!";
std::string smscId = "smscId";
std::string smscNumber = "smscNo";
std::string foreignId = "foreignId";
std::string service = "service";
std::string account = "account";
std::string dlrUrl = "http://example.com/dlr";
std::string charset = "ascii";
std::string boxId = "boxId";
std::string binInfo = "binInfo";
std::string metaData = "metaData";
auto time = 26748590;
auto mclass = blz::SmsMsg::Mclass::One;
auto mwi = blz::SmsMsg::Mwi::VoiceOn;
auto coding = blz::SmsMsg::SmsCoding::EightBit;
auto compress = true;
auto validity = 1;
auto deferred = 0;
auto dlrMask = 1;
auto pid = 1;
auto altDocs = 1;
auto rpi = 1;
auto msgLeft = 1;
auto splitParts = std::make_unique<blz::SplitParts>();
auto priority = 1;
auto resendTry = 1;
auto resendTime = 786545367;
return blz::SmsMsg(msgId, smsType, sender, receiver, udhData, msgData, smscId, smscNumber, foreignId, service,
account, time, mclass, mwi, coding, compress, validity, deferred, dlrMask, dlrUrl, pid, altDocs,
rpi, charset, boxId, binInfo, msgLeft, std::move(splitParts), priority, resendTry, resendTime, metaData);
}
TEST_CASE("Encode DCS using sms fields", "[sms]")
{
auto sms = getTestSms();
REQUIRE(sms.encodeDcs(blz::SmsMsg::DcsEncodeMode::Default) == 1);
}

我的项目结构:

project
|-------src
|------lib
|------ Msg.cpp
|------ Msg.hpp
|------ SplitParts.hpp
|------ SmsMsg.cpp
|------ SmsMsg.hpp
------ tests
|------ SmsMsgTest.cpp
------ CMakeLists.txt

CMakeLists的内容.txt:

cmake_minimum_required(VERSION 3.15)
project(Blaze)
set(BLZ_HEADERS
"${CMAKE_CURRENT_SOURCE_DIR}/src/lib/Msg.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/lib/SplitParts.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/SmsMsg.hpp"
)
set(BLZ_SOURCES
"${CMAKE_CURRENT_SOURCE_DIR}/src/lib/Msg.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/SmsMsg.cpp"
)
set(BLZ_TESTS
"${CMAKE_CURRENT_SOURCE_DIR}/tests/Setup.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/tests/SmsMsgTest.cpp"
)
set(Boost_USE_STATICLIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost 1.72.0 COMPONENTS system REQUIRED)
include_directories(${Boost_INCLUDE_DIRS})
add_library(Blz STATIC ${BLZ_HEADERS} ${BLZ_SOURCES})
target_link_libraries(Blz ${Boost_LIBRARIES})
### Tests
enable_testing()
find_package(Catch2 REQUIRED)
add_executable(BlzTests ${BLZ_TESTS})
target_include_directories(BlzTests PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/src")
target_include_directories(BlzTests PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/src/lib")
target_link_libraries(BlzTests Blz)
target_link_libraries(BlzTests Catch2::Catch2)
include(CTest)
include(Catch)
catch_discover_tests(BlzTests)

我得到的错误是:

Error   LNK2019 unresolved external symbol "public: __cdecl blz::SmsMsg::SmsMsg(struct boost::uuids::uuid,int,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &,int,enum blz::SmsMsg::Mclass,enum blz::SmsMsg::Mwi,enum blz::SmsMsg::SmsCoding,bool,int,int,int,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &,int,int,int,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &,int,class std::unique_ptr<class blz::SplitParts,struct std::default_delete<class blz::SplitParts> >,int,int,int,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &)" (??0SmsMsg@blz@@QEAA@Uuuid@uuids@boost@@HAEAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@11111111HW4Mclass@01@W4Mwi@01@W4SmsCoding@01@_NHHH1HHH111HV?$unique_ptr@VSplitParts@blz@@U?$default_delete@VSplitParts@blz@@@std@@@6@HHH1@Z) referenced in function "class blz::SmsMsg __cdecl getTestSms(void)" (?getTestSms@@YA?AVSmsMsg@blz@@XZ)

我正在使用Visual Studio IDE CMakeconfig:

{
"configurations": [
{
"name": "x64-Debug",
"generator": "Ninja",
"configurationType": "Debug",
"inheritEnvironments": ["msvc_x64_x64"],
"buildRoot": "${projectDir}\out\build\${name}",
"installRoot": "${projectDir}\out\install\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "-v",
"ctestCommandArgs": "",
"cmakeToolchain": "C:/Users/xxxx/.vcpkg/scripts/buildsystems/vcpkg.cmake",
"variables": []
}
]
}

[basic.def.odr]/4...内联函数或变量应在丢弃语句之外使用的每个翻译单元中定义。

SmsMsg的定义标记为inline,但在使用它的翻译单元中不可见。您的程序违反了一个定义规则,因此格式不正确。

inline关键字通常与标头中定义的函数一起使用。将其放在源文件中的函数定义中是没有意义的。