DCCL v4
Loading...
Searching...
No Matches
dynamic_protobuf.cpp
1// Copyright 2019-2023:
2// GobySoft, LLC (2013-)
3// Community contributors (see AUTHORS file)
4// File authors:
5// Toby Schneider <toby@gobysoft.org>
6//
7//
8// This file is part of the Dynamic Compact Control Language Library
9// ("DCCL").
10//
11// DCCL is free software: you can redistribute it and/or modify
12// it under the terms of the GNU Lesser General Public License as published by
13// the Free Software Foundation, either version 2.1 of the License, or
14// (at your option) any later version.
15//
16// DCCL is distributed in the hope that it will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19// GNU Lesser General Public License for more details.
20//
21// You should have received a copy of the GNU Lesser General Public License
22// along with DCCL. If not, see <http://www.gnu.org/licenses/>.
23#include "../../dynamic_protobuf_manager.h"
24#include <cassert>
25#include <dlfcn.h>
26#include <google/protobuf/descriptor.pb.h>
27#include <google/protobuf/text_format.h>
28#include <iostream>
29
30#include "test_a.pb.h"
31
32int main(int argc, char* argv[])
33{
34 if (argc != 2)
35 {
36 std::cerr << "Usage: " << argv[0] << " /path/to/libtest_dyn_protobuf" << std::endl;
37 exit(1);
38 }
39
40 void* dl_handle = dlopen(argv[1], RTLD_LAZY);
41
42 if (!dl_handle)
43 {
44 std::cerr << "Failed to open libtest_dyn_protobuf" SHARED_LIBRARY_SUFFIX
45 << ", error: " << dlerror() << std::endl;
46 exit(1);
47 }
48
49 std::shared_ptr<google::protobuf::SimpleDescriptorDatabase> simple_database(
50 new google::protobuf::SimpleDescriptorDatabase);
52
53 {
54 // testing compiled in
55 std::shared_ptr<google::protobuf::Message> adyn_msg =
57
58 std::cout << adyn_msg->GetDescriptor()->DebugString() << std::endl;
59
60 // testing dlopen'd
61 std::shared_ptr<google::protobuf::Message> bdyn_msg =
63
64 std::cout << bdyn_msg->GetDescriptor()->DebugString() << std::endl;
65
66 // test non-existent
67 try
68 {
69 std::shared_ptr<google::protobuf::Message> cdyn_msg =
71 // should throw
72 assert(false);
73 }
74 catch (std::exception& e)
75 {
76 // expected
77 }
78
79 // test dynamically loaded
80 google::protobuf::FileDescriptorProto d_proto;
81 std::string d_proto_str = "name: \"goby/test/util/dynamic_protobuf/test_d.proto\" "
82 "message_type { name: \"D\" field { name: \"d1\" "
83 "number: 1 label: LABEL_REQUIRED type: TYPE_DOUBLE } } ";
84
85 google::protobuf::TextFormat::ParseFromString(d_proto_str, &d_proto);
87
88 std::shared_ptr<google::protobuf::Message> ddyn_msg =
90
91 std::cout << ddyn_msg->GetDescriptor()->DebugString() << std::endl;
92
93 // test dynamically via separate database
94 google::protobuf::FileDescriptorProto e_proto;
95 std::string e_proto_str = "name: \"goby/test/util/dynamic_protobuf/test_e.proto\" "
96 "message_type { name: \"E\" field { name: \"e1\" "
97 "number: 1 label: LABEL_REQUIRED type: TYPE_DOUBLE } } ";
98
99 google::protobuf::TextFormat::ParseFromString(e_proto_str, &e_proto);
100
101 simple_database->Add(e_proto);
102
103 std::shared_ptr<google::protobuf::Message> edyn_msg =
105 std::cout << edyn_msg->GetDescriptor()->DebugString() << std::endl;
106
107 std::cout << "all tests passed" << std::endl;
108 }
109
110 dccl::DynamicProtobufManager::protobuf_shutdown();
111
112 dlclose(dl_handle);
113 return 0;
114}
static GoogleProtobufMessagePointer new_protobuf_message(const std::string &protobuf_type_name, bool user_pool_first=false)
Create a new (empty) Google Protobuf message of a given type by name.
static const google::protobuf::FileDescriptor * add_protobuf_file(const google::protobuf::FileDescriptorProto &proto)
Add a protobuf file defined in a google::protobuf::FileDescriptorProto.
static void add_database(std::shared_ptr< google::protobuf::DescriptorDatabase > database)
Add a Google Protobuf DescriptorDatabase to the set of databases searched for Message Descriptors.