shared_library_get_symbol_test.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. // Copyright 2011-2012 Renato Tegon Forti.
  2. // Copyright 2014 Renato Tegon Forti, Antony Polukhin.
  3. // Copyright 2015-2019 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. // For more information, see http://www.boost.org
  9. #include "../example/b2_workarounds.hpp"
  10. #include <boost/dll.hpp>
  11. #include <boost/core/lightweight_test.hpp>
  12. #include <boost/function.hpp>
  13. #include <boost/fusion/container.hpp>
  14. // lib functions
  15. typedef float (lib_version_func)();
  16. typedef void (say_hello_func) ();
  17. typedef int (increment) (int);
  18. typedef boost::fusion::vector<std::vector<int>, std::vector<int>, std::vector<int>, const std::vector<int>*, std::vector<int>* > do_share_res_t;
  19. typedef boost::shared_ptr<do_share_res_t> (do_share_t)(
  20. std::vector<int> v1,
  21. std::vector<int>& v2,
  22. const std::vector<int>& v3,
  23. const std::vector<int>* v4,
  24. std::vector<int>* v5
  25. );
  26. void refcountable_test(boost::dll::fs::path shared_library_path) {
  27. using namespace boost::dll;
  28. using namespace boost::fusion;
  29. std::vector<int> v(1000);
  30. {
  31. boost::function<say_hello_func> sz2
  32. = import<say_hello_func>(shared_library_path, "say_hello");
  33. sz2();
  34. sz2();
  35. sz2();
  36. }
  37. {
  38. boost::function<std::size_t(const std::vector<int>&)> sz
  39. = import_alias<std::size_t(const std::vector<int>&)>(shared_library_path, "foo_bar");
  40. BOOST_TEST(sz(v) == 1000);
  41. }
  42. {
  43. boost::function<do_share_t> f;
  44. {
  45. boost::function<do_share_t> f2 = import_alias<do_share_t>(shared_library_path, "do_share");
  46. f = f2;
  47. }
  48. std::vector<int> v1(1, 1), v2(2, 2), v3(3, 3), v4(4, 4), v5(1000, 5);
  49. boost::shared_ptr<do_share_res_t> res = f(v1, v2, v3, &v4, &v5);
  50. BOOST_TEST(at_c<0>(*res).size() == 1); BOOST_TEST(at_c<0>(*res).front() == 1);
  51. BOOST_TEST(at_c<1>(*res).size() == 2); BOOST_TEST(at_c<1>(*res).front() == 2);
  52. BOOST_TEST(at_c<2>(*res).size() == 3); BOOST_TEST(at_c<2>(*res).front() == 3);
  53. BOOST_TEST(at_c<3>(*res)->size() == 4); BOOST_TEST(at_c<3>(*res)->front() == 4);
  54. BOOST_TEST(at_c<4>(*res)->size() == 1000); BOOST_TEST(at_c<4>(*res)->front() == 5);
  55. BOOST_TEST(at_c<3>(*res) == &v4);
  56. BOOST_TEST(at_c<4>(*res) == &v5);
  57. BOOST_TEST(at_c<1>(*res).back() == 777);
  58. BOOST_TEST(v5.back() == 9990);
  59. }
  60. {
  61. boost::shared_ptr<int> i = import<int>(shared_library_path, "integer_g");
  62. BOOST_TEST(*i == 100);
  63. boost::shared_ptr<int> i2;
  64. i.swap(i2);
  65. BOOST_TEST(*i2 == 100);
  66. }
  67. {
  68. boost::function<int&()> f = import_alias<int&()>(shared_library_path, "ref_returning_function");
  69. BOOST_TEST(f() == 0);
  70. f() = 10;
  71. BOOST_TEST(f() == 10);
  72. boost::function<int&()> f1 = import_alias<int&()>(shared_library_path, "ref_returning_function");
  73. BOOST_TEST(f1() == 10);
  74. f1() += 10;
  75. BOOST_TEST(f() == 20);
  76. }
  77. {
  78. boost::shared_ptr<const int> i = import<const int>(shared_library_path, "const_integer_g");
  79. BOOST_TEST(*i == 777);
  80. boost::shared_ptr<const int> i2 = i;
  81. i.reset();
  82. BOOST_TEST(*i2 == 777);
  83. }
  84. {
  85. boost::shared_ptr<std::string> s = import_alias<std::string>(shared_library_path, "info");
  86. BOOST_TEST(*s == "I am a std::string from the test_library (Think of me as of 'Hello world'. Long 'Hello world').");
  87. boost::shared_ptr<std::string> s2;
  88. s.swap(s2);
  89. BOOST_TEST(*s2 == "I am a std::string from the test_library (Think of me as of 'Hello world'. Long 'Hello world').");
  90. }
  91. }
  92. // exe function
  93. extern "C" int BOOST_SYMBOL_EXPORT exef() {
  94. return 15;
  95. }
  96. // Unit Tests
  97. int main(int argc, char* argv[]) {
  98. using namespace boost::dll;
  99. boost::dll::fs::path shared_library_path = b2_workarounds::first_lib_from_argv(argc, argv);
  100. BOOST_TEST(shared_library_path.string().find("test_library") != std::string::npos);
  101. BOOST_TEST(b2_workarounds::is_shared_library(shared_library_path));
  102. refcountable_test(shared_library_path);
  103. shared_library sl(shared_library_path);
  104. BOOST_TEST(sl.get<int>("integer_g") == 100);
  105. sl.get<int>("integer_g") = 10;
  106. BOOST_TEST(sl.get<int>("integer_g") == 10);
  107. BOOST_TEST(sl.get<int>(std::string("integer_g")) == 10);
  108. BOOST_TEST(sl.get<say_hello_func>("say_hello"));
  109. sl.get<say_hello_func>("say_hello")();
  110. float ver = sl.get<lib_version_func>("lib_version")();
  111. BOOST_TEST(ver == 1.0);
  112. int n = sl.get<increment>("increment")(1);
  113. BOOST_TEST(n == 2);
  114. BOOST_TEST(sl.get<const int>("const_integer_g") == 777);
  115. boost::function<int(int)> inc = sl.get<int(int)>("increment");
  116. BOOST_TEST(inc(1) == 2);
  117. BOOST_TEST(inc(2) == 3);
  118. BOOST_TEST(inc(3) == 4);
  119. // Checking that symbols are still available, after another load+unload of the library
  120. { shared_library sl2(shared_library_path); }
  121. BOOST_TEST(inc(1) == 2);
  122. BOOST_TEST(sl.get<int>("integer_g") == 10);
  123. // Checking aliases
  124. boost::function<std::size_t(const std::vector<int>&)> sz
  125. = sl.get_alias<std::size_t(const std::vector<int>&)>("foo_bar");
  126. std::vector<int> v(10);
  127. BOOST_TEST(sz(v) == 10);
  128. BOOST_TEST(sl.get_alias<std::size_t>("foo_variable") == 42);
  129. sz = sl.get<std::size_t(*)(const std::vector<int>&)>("foo_bar");
  130. BOOST_TEST(sz(v) == 10);
  131. BOOST_TEST(*sl.get<std::size_t*>("foo_variable") == 42);
  132. { // self
  133. shared_library sl(program_location());
  134. int val = sl.get<int(void)>("exef")();
  135. BOOST_TEST(val == 15);
  136. }
  137. int& reference_to_internal_integer = sl.get<int&>("reference_to_internal_integer");
  138. BOOST_TEST(reference_to_internal_integer == 0xFF0000);
  139. #ifndef BOOST_NO_RVALUE_REFERENCES
  140. int&& rvalue_reference_to_internal_integer = sl.get<int&&>("rvalue_reference_to_internal_integer");
  141. BOOST_TEST(rvalue_reference_to_internal_integer == 0xFF0000);
  142. #endif
  143. return boost::report_errors();
  144. }