c++ - 库链接期间未找到参考
问题描述
我在 C++ 中创建了一个名为 libparse 的库,该代码由另一个名为 libitcmpmsg.so 的库使用。
我一直在尝试在 test.cpp 中测试 libitcmpmsg ,但是当我尝试构建它时,编译器会返回以下消息:
$libpath/libitcmpmsg.so: reference not found to "void MSG_PARSER::WriteBigEndian<unsigned char>(std::vector<unsigned char, std::allocator<unsigned char> &, unsingned char)"
$libpath/libitcmpmsg.so: reference not found to "unsigned char* MSG_PARSER::ReadBigEndian<unsigned char>(unsigned char&, unsigned char*, unsigned int&)"
$libpath/libitcmpmsg.so: reference not found to "MSG_PARSER::ReadFixedLengthString(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, unsigned char*, int, unsigned int&)"
$libpath/libitcmpmsg.so: reference not found to "MSG_PARSER::WriteFixedLengthString(std::vector<unsigned char, std::allocator<unsigned char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int)"
libpath 仅代表库的路径。MSG_PARSER 是来自 libparser 的命名空间。
从错误消息来看,msg_parser.h 中函数的作用域是:
template <class T>
void WriteBigEndian(std::vector<uint8_t>& target, T source);
template <class T>
uint8_t* ReadBigEndian(T &target, uint8_t* source, uint32_t &available);
uint8_t* ReadFixedLengthString(string& target, uint8_t *source, int size, uint32_t &available);
void WriteFixedLengthString(std::vector<uint8_t> &target, const string& source, uint32_t size);
似乎 libitcmpmsg 将错误类型的参数传递给 libparser.so。下面是一个代码片段,其中 libparer.so 被 libitcmpmsg.so 使用
#include "ptcinteraction.h"
#include "msg_parser.h"
#include <stdint.h>
using namespace PTC_INTERACTION;
using namespace MSG_PARSER;
PtcInteraction::PtcInteraction( std::vector<uint8_t> &data )
{
m_msgBuffer.clear();
uint32_t tavailable = static_cast<uint32_t>(data.size());
uint8_t *tsource = &data[0];
uint8_t value = 0;
tsource = ReadFixedLengthString(m_message.railScac, tsource, SCAC_SIZE, tavailable);
tsource = ReadBigEndian<uint8_t>(m_message.sizeOfPromptTxt, tsource, tavailable );
tsource = ReadFixedLengthString(m_message.promptTxt, tsource, m_message.sizeOfPromptTxt, tavailable);
tsource = ReadBigEndian<uint8_t>(m_message.sizeOfKeyPressedTxt, tsource, tavailable );
tsource = ReadFixedLengthString(m_message.keyPressedTxt, tsource, m_message.sizeOfKeyPressedTxt, tavailable);
if((&data[0] + data.size()) == tsource)
{
m_msgBuffer = data;
}
else
{
m_msgBuffer = {};
}
}
PtcInteraction::PtcInteraction( OCCPTCMSG::PtcInteractionT &ptcInteraction)
{
m_msgBuffer.clear();
m_message = ptcInteraction;
WriteFixedLengthString(m_msgBuffer, ptcInteraction.railScac, SCAC_SIZE);
WriteBigEndian<uint8_t>(m_msgBuffer, ptcInteraction.sizeOfPromptTxt );
.
.
.
PTCInteraction 是来自 libitcmpmsg.so 的一个类,而 PtcInteractionT 是一个同样由 libitcmpmsg 定义的结构。
测试代码如下所示:
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include "ptcinteraction.h"
#include "occptcmessages_generated.h"
#include "msg_parser.h"
#include <cstdio>
using namespace PTC_INTERACTION;
int main(void)
{
OCCPTCMSG::PtcInteractionT teste;
teste.railScac = "abcd";
teste.promptTxt = "message test";
teste.sizeOfPromptTxt = teste.promptTxt.size();
teste.keyPressedTxt = "test";
teste.sizeOfKeyPressedTxt = teste.keyPressedTxt.size();
PTC_INTERACTION::PtcInteraction ptcInter(teste);
PTC_INTERACTION::PtcInteraction ptcInter2(ptcInter.m_msgBuffer);
if ( (ptcInter.m_message.railScac == ptcInter2.m_message.railScac) &&
(ptcInter.m_message.promptTxt == ptcInter2.m_message.promptTxt) &&
(ptcInter.m_message.sizeOfPromptTxt == ptcInter2.m_message.sizeOfPromptTxt) &&
(ptcInter.m_message.keyPressedTxt == ptcInter2.m_message.keyPressedTxt) &&
(ptcInter.m_message.sizeOfKeyPressedTxt == ptcInter2.m_message.sizeOfKeyPressedTxt) )
{
std::cout << "Serialization and deserialization succeeded" << std::endl;
}
}
代码开发中使用了 3 个 CMakeList:
- 库解析器生成器;
- libitcmpmsg 生成器;
- 测试生成器。
有谁知道为什么编译器会返回问题开头描述的 4 条错误消息?
我该如何解决这些问题?
如果您需要 CMakeLists 代码来更好地理解问题,请告诉我。
解决方案
您必须在 cpp 中实例化专门的模板类,或者将模板类的主体放在标题中:https ://isocpp.org/wiki/faq/templates#templates-defn-vs-decl
推荐阅读
- javascript - 使用 getAttribute() 方法获取“null”
- python - 检查字典键名,这是一个类的实例
- android - CAMERA_ROLL 权限返回被拒绝,即使用户授予它
- laravel - 更改 laravel 默认用户 ID
- pandas - 'DataFrame' 对象在 google colaboratory 中不可调用
- python - 如何在 Python 中使用 BeatifulSoup 获取页数
- python - Tensorflow - Train.py - ValueError: ('%s is not decorated with @add_arg_scope', ('nets.mobilenet.mobilenet', 'depth_multiplier'))
- php - Laravel 中带有数组名称的 html 表单元素的自定义错误消息
- c++ - 需要有关此 if 语句的帮助
- mysql - 发送 put 请求时,updatedAt 列未使用最新日期时间更新