• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2011-2012 Renato Tegon Forti.
2 // Copyright 2014 Renato Tegon Forti, Antony Polukhin.
3 // Copyright 2015-2020 Antony Polukhin.
4 //
5 // Distributed under the Boost Software License, Version 1.0.
6 // (See accompanying file LICENSE_1_0.txt
7 // or copy at http://www.boost.org/LICENSE_1_0.txt)
8 
9 // For more information, see http://www.boost.org
10 
11 #include "../example/b2_workarounds.hpp"
12 #include <boost/dll.hpp>
13 #include <boost/core/lightweight_test.hpp>
14 #include <boost/function.hpp>
15 #include <boost/fusion/container.hpp>
16 // lib functions
17 
18 typedef float (lib_version_func)();
19 typedef void  (say_hello_func)  ();
20 typedef int   (increment)       (int);
21 
22 typedef boost::fusion::vector<std::vector<int>, std::vector<int>, std::vector<int>, const std::vector<int>*, std::vector<int>* > do_share_res_t;
23 typedef boost::shared_ptr<do_share_res_t> (do_share_t)(
24             std::vector<int> v1,
25             std::vector<int>& v2,
26             const std::vector<int>& v3,
27             const std::vector<int>* v4,
28             std::vector<int>* v5
29         );
30 
refcountable_test(boost::dll::fs::path shared_library_path)31 void refcountable_test(boost::dll::fs::path shared_library_path) {
32     using namespace boost::dll;
33     using namespace boost::fusion;
34 
35     std::vector<int> v(1000);
36 
37     {
38         boost::function<say_hello_func> sz2
39             = import<say_hello_func>(shared_library_path, "say_hello");
40 
41         sz2();
42         sz2();
43         sz2();
44     }
45 
46     {
47         boost::function<std::size_t(const std::vector<int>&)> sz
48             = import_alias<std::size_t(const std::vector<int>&)>(shared_library_path, "foo_bar");
49         BOOST_TEST(sz(v) == 1000);
50     }
51 
52 
53     {
54         boost::function<do_share_t> f;
55 
56         {
57             boost::function<do_share_t> f2 = import_alias<do_share_t>(shared_library_path, "do_share");
58             f = f2;
59         }
60 
61         std::vector<int> v1(1, 1), v2(2, 2), v3(3, 3), v4(4, 4), v5(1000, 5);
62         boost::shared_ptr<do_share_res_t> res = f(v1, v2, v3, &v4, &v5);
63 
64         BOOST_TEST(at_c<0>(*res).size() == 1); BOOST_TEST(at_c<0>(*res).front() == 1);
65         BOOST_TEST(at_c<1>(*res).size() == 2); BOOST_TEST(at_c<1>(*res).front() == 2);
66         BOOST_TEST(at_c<2>(*res).size() == 3); BOOST_TEST(at_c<2>(*res).front() == 3);
67         BOOST_TEST(at_c<3>(*res)->size() == 4); BOOST_TEST(at_c<3>(*res)->front() == 4);
68         BOOST_TEST(at_c<4>(*res)->size() == 1000); BOOST_TEST(at_c<4>(*res)->front() == 5);
69 
70         BOOST_TEST(at_c<3>(*res) == &v4);
71         BOOST_TEST(at_c<4>(*res) == &v5);
72         BOOST_TEST(at_c<1>(*res).back() == 777);
73         BOOST_TEST(v5.back() == 9990);
74     }
75 
76     {
77         boost::shared_ptr<int> i = import<int>(shared_library_path, "integer_g");
78         BOOST_TEST(*i == 100);
79 
80         boost::shared_ptr<int> i2;
81         i.swap(i2);
82         BOOST_TEST(*i2 == 100);
83     }
84 
85     {
86         boost::function<int&()> f = import_alias<int&()>(shared_library_path, "ref_returning_function");
87         BOOST_TEST(f() == 0);
88 
89         f() = 10;
90         BOOST_TEST(f() == 10);
91 
92         boost::function<int&()> f1 = import_alias<int&()>(shared_library_path, "ref_returning_function");
93         BOOST_TEST(f1() == 10);
94 
95         f1() += 10;
96         BOOST_TEST(f() == 20);
97     }
98 
99     {
100         boost::shared_ptr<const int> i = import<const int>(shared_library_path, "const_integer_g");
101         BOOST_TEST(*i == 777);
102 
103         boost::shared_ptr<const int> i2 = i;
104         i.reset();
105         BOOST_TEST(*i2 == 777);
106     }
107 
108     {
109         boost::shared_ptr<std::string> s = import_alias<std::string>(shared_library_path, "info");
110         BOOST_TEST(*s == "I am a std::string from the test_library (Think of me as of 'Hello world'. Long 'Hello world').");
111 
112         boost::shared_ptr<std::string> s2;
113         s.swap(s2);
114         BOOST_TEST(*s2 == "I am a std::string from the test_library (Think of me as of 'Hello world'. Long 'Hello world').");
115     }
116 }
117 
118 // exe function
exef()119 extern "C" int BOOST_SYMBOL_EXPORT exef() {
120     return 15;
121 }
122 
123 // Unit Tests
main(int argc,char * argv[])124 int main(int argc, char* argv[]) {
125     using namespace boost::dll;
126 
127     boost::dll::fs::path shared_library_path = b2_workarounds::first_lib_from_argv(argc, argv);
128     BOOST_TEST(shared_library_path.string().find("test_library") != std::string::npos);
129     BOOST_TEST(b2_workarounds::is_shared_library(shared_library_path));
130 
131     refcountable_test(shared_library_path);
132 
133     shared_library sl(shared_library_path);
134 
135     BOOST_TEST(sl.get<int>("integer_g") == 100);
136 
137     sl.get<int>("integer_g") = 10;
138     BOOST_TEST(sl.get<int>("integer_g") == 10);
139     BOOST_TEST(sl.get<int>(std::string("integer_g")) == 10);
140 
141     BOOST_TEST(sl.get<say_hello_func>("say_hello"));
142     sl.get<say_hello_func>("say_hello")();
143 
144     float ver = sl.get<lib_version_func>("lib_version")();
145     BOOST_TEST(ver == 1.0);
146 
147     int n = sl.get<increment>("increment")(1);
148     BOOST_TEST(n == 2);
149 
150     BOOST_TEST(sl.get<const int>("const_integer_g") == 777);
151 
152     boost::function<int(int)> inc = sl.get<int(int)>("increment");
153     BOOST_TEST(inc(1) == 2);
154     BOOST_TEST(inc(2) == 3);
155     BOOST_TEST(inc(3) == 4);
156 
157     // Checking that symbols are still available, after another load+unload of the library
158     { shared_library sl2(shared_library_path); }
159 
160     BOOST_TEST(inc(1) == 2);
161     BOOST_TEST(sl.get<int>("integer_g") == 10);
162 
163 
164     // Checking aliases
165     boost::function<std::size_t(const std::vector<int>&)> sz
166         = sl.get_alias<std::size_t(const std::vector<int>&)>("foo_bar");
167 
168     std::vector<int> v(10);
169     BOOST_TEST(sz(v) == 10);
170     BOOST_TEST(sl.get_alias<std::size_t>("foo_variable") == 42);
171 
172 
173     sz = sl.get<std::size_t(*)(const std::vector<int>&)>("foo_bar");
174     BOOST_TEST(sz(v) == 10);
175     BOOST_TEST(*sl.get<std::size_t*>("foo_variable") == 42);
176 
177     { // self
178         shared_library sl(program_location());
179         int val = sl.get<int(void)>("exef")();
180         BOOST_TEST(val == 15);
181     }
182 
183     int& reference_to_internal_integer = sl.get<int&>("reference_to_internal_integer");
184     BOOST_TEST(reference_to_internal_integer == 0xFF0000);
185 
186 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
187     int&& rvalue_reference_to_internal_integer = sl.get<int&&>("rvalue_reference_to_internal_integer");
188     BOOST_TEST(rvalue_reference_to_internal_integer == 0xFF0000);
189 #endif
190 
191     return boost::report_errors();
192 }
193 
194