]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Copyright 2011-2012 Renato Tegon Forti. |
2 | // Copyright 2014 Renato Tegon Forti, Antony Polukhin. | |
92f5a8d4 | 3 | // Copyright 2015-2019 Antony Polukhin. |
7c673cae FG |
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 | ||
92f5a8d4 | 31 | void refcountable_test(boost::dll::fs::path shared_library_path) { |
7c673cae FG |
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 | |
119 | extern "C" int BOOST_SYMBOL_EXPORT exef() { | |
120 | return 15; | |
121 | } | |
122 | ||
123 | // Unit Tests | |
124 | int main(int argc, char* argv[]) { | |
125 | using namespace boost::dll; | |
126 | ||
92f5a8d4 | 127 | boost::dll::fs::path shared_library_path = b2_workarounds::first_lib_from_argv(argc, argv); |
7c673cae FG |
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_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 |