编译报错如下:CMakeFiles/t3_node.dir/src/main.cpp.o: In function `boost::asio::ssl::detail::openssl_init_base::do_init::~do_init()': main.cpp:(.text._ZN5boost4asio3ssl6detail17openssl_init_base7do_initD2Ev[_ZN5boost4asio3ssl6detail17openssl_init_base7do_initD5Ev]+0x12): undefined reference to `CONF_modules_unload' CMakeFiles/t3_node.dir/src/main.cpp.o: In function `boost::asio::error::detail::ssl_category::message[abi:cxx11](int) const': main.cpp:(.text._ZNK5boost4asio5error6detail12ssl_category7messageB5cxx11Ei[_ZNK5boost4asio5error6detail12ssl_category7messageB5cxx11Ei]+0x2c): undefined reference to `ERR_reason_error_string' main.cpp:(.text._ZNK5boost4asio5error6detail12ssl_category7messageB5cxx11Ei[_ZNK5boost4asio5error6detail12ssl_category7messageB5cxx11Ei]+0x48): undefined reference to `ERR_lib_error_string' main.cpp:(.text._ZNK5boost4asio5error6detail12ssl_category7messageB5cxx11Ei[_ZNK5boost4asio5error6detail12ssl_category7messageB5cxx11Ei]+0x59): undefined reference to `ERR_func_error_string' collect2: error: ld returned 1 exit status t3/CMakeFiles/t3_node.dir/build.make:318: recipe for target '/smartview/devel/lib/t3/t3_node' failed make[2]: *** [/smartview/devel/lib/t3/t3_node] Error 1 CMakeFiles/Makefile2:3555: recipe for target 't3/CMakeFiles/t3_node.dir/all' failed make[1]: *** [t3/CMakeFiles/t3_node.dir/all] Error 2 make[1]: *** Waiting for unfinished jobs.... [ 96%] Built target play_node [100%] Built target smartview_handler Makefile:145: recipe for target 'all' failed make: *** [all] Error 2 Invoking "make -j20 -l20" failed
时间: 2024-03-16 10:41:33 浏览: 370
这个错误提示表明在链接时找不到OpenSSL库。你可以尝试在CMakeLists.txt文件中添加链接OpenSSL库的代码,如下所示:
```
find_package(OpenSSL REQUIRED)
target_link_libraries(your_project_name OpenSSL::SSL OpenSSL::Crypto)
```
其中,your_project_name是你的项目名。这个代码片段会在链接你的项目时添加OpenSSL库。如果仍然无法解决问题,你可以检查一下OpenSSL库是否正确安装并且库的路径是否正确添加到系统路径中。
相关问题
帮我修改代码,实现用wss发送serialized_data到wss://autopilot-test.t3go.cn:443/api/v1/vehicle/push/message/LFB1FV696M2L43840。 main.cpp: #include "ros/ros.h" #include "std_msgs/String.h" #include <boost/thread/locks.hpp> #include <boost/thread/shared_mutex.hpp> #include "third_party/apollo/proto/perception/perception_obstacle.pb.h" #include "t3_perception.pb.h" apollo::perception::PerceptionObstacles perception_obstacles_; void perceptionCallback(const std_msgs::String& msg) { ROS_WARN("t3 perceptionCallback parse"); if (perception_obstacles_.ParseFromString(msg.data)) { double timestamp = perception_obstacles_.header().timestamp_sec(); ROS_INFO("t3 perceptionCallback timestamp %f count:%d", timestamp, perception_obstacles_.perception_obstacle().size()); std::string data; perception_obstacles_.SerializeToString(&data); VehData veh_data; veh_data.set_messagetype(5); veh_data.set_messagedes("PerceptionObstacles"); veh_data.set_contents(data); std::string serialized_data; veh_data.SerializeToString(&serialized_data); } else { ROS_ERROR("t3 perceptionCallback parse fail!"); } } int main(int argc, char **argv) { ros::init(argc, argv, "listener"); ros::NodeHandle n; ros::Subscriber sub = n.subscribe("/perception_node/perception_objects", 1000, perceptionCallback); ros::spin(); return 0; } t3_perception.proto: syntax = "proto3"; option java_package = "com.t3.ts.dt.ad.web.protobuf"; option java_outer_classname = "VehDTO"; option java_multiple_files = false; message VehData { /** messageType: 1:客户端心跳 2:云端心跳响应 3:连接成功 4:连接失败 5:客户端发送消息 6:云端发送消息 7:消息处理成功 8:消息处理失败 9:此客户端未注册 10:未知消息类型 */ int32 messageType = 1; string messageDes = 2; bytes contents = 3; // 发送内容 }
您可以使用以下代码实现发送 `serialized_data` 到 `wss://autopilot-test.t3go.cn:443/api/v1/vehicle/push/message/LFB1FV696M2L43840`:
```cpp
#include "ros/ros.h"
#include "std_msgs/String.h"
#include <boost/thread/locks.hpp>
#include <boost/thread/shared_mutex.hpp>
#include "third_party/apollo/proto/perception/perception_obstacle.pb.h"
#include "t3_perception.pb.h"
#include "websocketpp/config/asio_client.hpp"
#include "websocketpp/client.hpp"
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
using websocketpp::lib::bind;
typedef websocketpp::client<websocketpp::config::asio_tls_client> client;
typedef boost::shared_ptr<boost::asio::ssl::context> context_ptr;
context_ptr on_tls_init(websocketpp::connection_hdl) {
context_ptr ctx = boost::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::tlsv12);
try {
ctx->set_options(boost::asio::ssl::context::default_workarounds |
boost::asio::ssl::context::no_sslv2 |
boost::asio::ssl::context::no_sslv3 |
boost::asio::ssl::context::single_dh_use);
} catch (std::exception& e) {
std::cout << e.what() << std::endl;
}
return ctx;
}
void on_open(client* c, websocketpp::connection_hdl hdl) {
std::string message = "Hello, world!";
try {
c->send(hdl, message, websocketpp::frame::opcode::text);
} catch (websocketpp::exception const & e) {
std::cout << e.what() << std::endl;
}
}
void on_fail(client* c, websocketpp::connection_hdl hdl) {
client::connection_ptr con = c->get_con_from_hdl(hdl);
std::cout << "Connection to " << con->get_uri() << " failed: " << con->get_ec().message() << std::endl;
}
void on_message(websocketpp::connection_hdl hdl, client::message_ptr msg) {
std::cout << "Received message: " << msg->get_payload() << std::endl;
}
void perceptionCallback(const std_msgs::String& msg) {
ROS_WARN("t3 perceptionCallback parse");
apollo::perception::PerceptionObstacles perception_obstacles_;
if (perception_obstacles_.ParseFromString(msg.data)) {
double timestamp = perception_obstacles_.header().timestamp_sec();
ROS_INFO("t3 perceptionCallback timestamp %f count:%d", timestamp, perception_obstacles_.perception_obstacle().size());
std::string data;
perception_obstacles_.SerializeToString(&data);
VehData veh_data;
veh_data.set_messagetype(5);
veh_data.set_messagedes("PerceptionObstacles");
veh_data.set_contents(data);
std::string serialized_data;
veh_data.SerializeToString(&serialized_data);
// 创建 websocket 客户端
client c;
std::string uri = "wss://autopilot-test.t3go.cn:443/api/v1/vehicle/push/message/LFB1FV696M2L43840";
try {
// 设置 TLS 初始化回调函数
c.set_tls_init_handler(bind(&on_tls_init, ::_1));
// 设置回调函数
c.set_open_handler(bind(&on_open, &c, ::_1));
c.set_fail_handler(bind(&on_fail, &c, ::_1));
c.set_message_handler(bind(&on_message, ::_1, ::_2));
// 连接服务器
websocketpp::lib::error_code ec;
client::connection_ptr con = c.get_connection(uri, ec);
if (ec) {
std::cout << "Could not create connection: " << ec.message() << std::endl;
return;
}
c.connect(con);
// 发送数据
c.send(con->get_handle(), serialized_data, websocketpp::frame::opcode::binary);
// 等待连接关闭
c.run();
} catch (websocketpp::exception const & e) {
std::cout << e.what() << std::endl;
}
} else {
ROS_ERROR("t3 perceptionCallback parse fail!");
}
}
int main(int argc, char **argv) {
ros::init(argc, argv, "listener");
ros::NodeHandle n;
ros::Subscriber sub = n.subscribe("/perception_node/perception_objects", 1000, perceptionCallback);
ros::spin();
return 0;
}
```
在上面的代码中,我们使用了 websocketpp 库来创建 websocket 客户端,并发送二进制数据到指定的服务器。在 `perceptionCallback` 函数中,我们将解析得到的 Protobuf 数据序列化为二进制数据,并发送到服务器。
请注意,这里我们使用了 TLS 加密的 websocket 连接,因此需要设置 TLS 初始化回调函数来初始化 SSL 上下文。同时,我们也设置了连接成功、连接失败和收到消息的回调函数。
报错error: ‘thread_pool’ is not a member of ‘boost::asio’
这个错误是因为在Boost.Asio库中没有找到`thread_pool`类的成员。`thread_pool`类在较新的Boost版本中是不再提供的。
如果你想使用线程池功能,可以考虑使用Boost.Asio库中提供的其他替代方案。例如,你可以使用`io_context`和`executor_work_guard`来实现线程池的功能。下面是一个简单的示例代码:
```cpp
#include <boost/asio.hpp>
#include <iostream>
class ThreadPool {
public:
ThreadPool(size_t numThreads) : work_(ioContext_) {
for (size_t i = 0; i < numThreads; ++i) {
threads_.emplace_back([this]() { ioContext_.run(); });
}
}
~ThreadPool() {
ioContext_.stop();
for (auto& thread : threads_) {
thread.join();
}
}
template <typename Task>
void post(Task&& task) {
boost::asio::post(ioContext_, std::forward<Task>(task));
}
private:
boost::asio::io_context ioContext_;
boost::asio::executor_work_guard<boost::asio::io_context::executor_type> work_;
std::vector<std::thread> threads_;
};
int main() {
ThreadPool threadPool(4);
for (int i = 0; i < 10; ++i) {
threadPool.post([i]() {
std::cout << "Task " << i << " executed in thread " << std::this_thread::get_id() << std::endl;
});
}
std::this_thread::sleep_for(std::chrono::seconds(2));
return 0;
}
```
在这个示例中,我们使用了`io_context`和`executor_work_guard`来创建了一个简单的线程池。`post`方法用于将任务提交到线程池中执行。
请确保在编译时链接了Boost.Asio库,并将头文件路径正确地包含在编译器的搜索路径中。希望这能帮助你解决问题。如有更多疑问,请随时提问。
阅读全文
相关推荐














