1 // Copyright 2011-2012 Renato Tegon Forti.
2 // Copyright 2014 Renato Tegon Forti, Antony Polukhin.
3 // Copyright 2015-2019 Antony Polukhin.
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)
9 // For more information, see http://www.boost.org
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>
18 typedef float (lib_version_func
)();
19 typedef void (say_hello_func
) ();
20 typedef int (increment
) (int);
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
)(
26 const std::vector
<int>& v3
,
27 const std::vector
<int>* v4
,
31 void refcountable_test(boost::dll::fs::path shared_library_path
) {
32 using namespace boost::dll
;
33 using namespace boost::fusion
;
35 std::vector
<int> v(1000);
38 boost::function
<say_hello_func
> sz2
39 = import
<say_hello_func
>(shared_library_path
, "say_hello");
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);
54 boost::function
<do_share_t
> f
;
57 boost::function
<do_share_t
> f2
= import_alias
<do_share_t
>(shared_library_path
, "do_share");
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
);
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);
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);
77 boost::shared_ptr
<int> i
= import
<int>(shared_library_path
, "integer_g");
78 BOOST_TEST(*i
== 100);
80 boost::shared_ptr
<int> i2
;
82 BOOST_TEST(*i2
== 100);
86 boost::function
<int&()> f
= import_alias
<int&()>(shared_library_path
, "ref_returning_function");
90 BOOST_TEST(f() == 10);
92 boost::function
<int&()> f1
= import_alias
<int&()>(shared_library_path
, "ref_returning_function");
93 BOOST_TEST(f1() == 10);
96 BOOST_TEST(f() == 20);
100 boost::shared_ptr
<const int> i
= import
<const int>(shared_library_path
, "const_integer_g");
101 BOOST_TEST(*i
== 777);
103 boost::shared_ptr
<const int> i2
= i
;
105 BOOST_TEST(*i2
== 777);
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').");
112 boost::shared_ptr
<std::string
> s2
;
114 BOOST_TEST(*s2
== "I am a std::string from the test_library (Think of me as of 'Hello world'. Long 'Hello world').");
119 extern "C" int BOOST_SYMBOL_EXPORT
exef() {
124 int main(int argc
, char* argv
[]) {
125 using namespace boost::dll
;
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
));
131 refcountable_test(shared_library_path
);
133 shared_library
sl(shared_library_path
);
135 BOOST_TEST(sl
.get
<int>("integer_g") == 100);
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);
141 BOOST_TEST(sl
.get
<say_hello_func
>("say_hello"));
142 sl
.get
<say_hello_func
>("say_hello")();
144 float ver
= sl
.get
<lib_version_func
>("lib_version")();
145 BOOST_TEST(ver
== 1.0);
147 int n
= sl
.get
<increment
>("increment")(1);
150 BOOST_TEST(sl
.get
<const int>("const_integer_g") == 777);
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);
157 // Checking that symbols are still available, after another load+unload of the library
158 { shared_library
sl2(shared_library_path
); }
160 BOOST_TEST(inc(1) == 2);
161 BOOST_TEST(sl
.get
<int>("integer_g") == 10);
165 boost::function
<std::size_t(const std::vector
<int>&)> sz
166 = sl
.get_alias
<std::size_t(const std::vector
<int>&)>("foo_bar");
168 std::vector
<int> v(10);
169 BOOST_TEST(sz(v
) == 10);
170 BOOST_TEST(sl
.get_alias
<std::size_t>("foo_variable") == 42);
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);
178 shared_library
sl(program_location());
179 int val
= sl
.get
<int(void)>("exef")();
180 BOOST_TEST(val
== 15);
183 int& reference_to_internal_integer
= sl
.get
<int&>("reference_to_internal_integer");
184 BOOST_TEST(reference_to_internal_integer
== 0xFF0000);
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);
191 return boost::report_errors();