1 // (C) Copyright Gennadiy Rozental 2005-2014.
2 // Distributed under the Boost Software License, Version 1.0.
3 // (See accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
6 // See http://www.boost.org/libs/test for the library home page.
9 #ifndef BOOST_TEST_DYN_LINK
10 #define BOOST_TEST_DYN_LINK
12 #include <boost/test/unit_test.hpp>
14 // Boost.Runtime.Param
15 #include <boost/test/utils/runtime/cla/named_parameter.hpp>
16 #include <boost/test/utils/runtime/cla/parser.hpp>
18 namespace rt
= boost::runtime
;
19 namespace cla
= boost::runtime::cla
;
24 //_________________________________________________________________//
30 #if defined(BOOST_WINDOWS) && !defined(BOOST_DISABLE_WIN32) // WIN32 API
34 typedef HINSTANCE handle
;
37 open( std::string
const& file_name
)
39 return LoadLibrary( file_name
.c_str() );
42 //_________________________________________________________________//
44 template<typename TargType
>
46 locate_symbol( handle h
, std::string
const& symbol
)
48 return reinterpret_cast<TargType
>( GetProcAddress( h
, symbol
.c_str() ) );
51 //_________________________________________________________________//
60 //_________________________________________________________________//
67 FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
,
70 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
74 std::string
res( msg
);
82 //_________________________________________________________________//
84 #elif defined(BOOST_HAS_UNISTD_H) // POSIX API
88 #include <sys/types.h>
96 open( std::string
const& file_name
)
98 return dlopen( file_name
.c_str(), RTLD_LOCAL
| RTLD_LAZY
);
101 //_________________________________________________________________//
103 template<typename TargType
>
105 locate_symbol( handle h
, std::string
const& symbol
)
107 return reinterpret_cast<TargType
>( dlsym( h
, symbol
.c_str() ) );
110 //_________________________________________________________________//
119 //_________________________________________________________________//
127 //_________________________________________________________________//
131 #error "Dynamic library API is unknown"
135 } // namespace dyn_lib
137 //____________________________________________________________________________//
139 static std::string test_lib_name
;
140 static std::string
init_func_name( "init_unit_test" );
142 dyn_lib::handle test_lib_handle
;
146 typedef bool (*init_func_ptr
)();
147 init_func_ptr init_func
;
149 test_lib_handle
= dyn_lib::open( test_lib_name
);
150 if( !test_lib_handle
)
151 throw std::logic_error( std::string("Fail to load test library: ")
152 .append( dyn_lib::error() ) );
154 init_func
= dyn_lib::locate_symbol
<init_func_ptr
>( test_lib_handle
, init_func_name
);
157 throw std::logic_error( std::string("Can't locate test initilization function ")
158 .append( init_func_name
)
160 .append( dyn_lib::error() ) );
162 return (*init_func
)();
165 //____________________________________________________________________________//
167 int main( int argc
, char* argv
[] )
172 P
- cla::ignore_mismatch
173 << cla::named_parameter
<rt::cstring
>( "test" ) - (cla::prefix
= "--")
174 << cla::named_parameter
<rt::cstring
>( "init" ) - (cla::prefix
= "--",cla::optional
);
176 P
.parse( argc
, argv
);
178 assign_op( test_lib_name
, P
.get( "test" ), 0 );
180 assign_op( init_func_name
, P
.get( "init" ), 0 );
182 int res
= ::boost::unit_test::unit_test_main( &load_test_lib
, argc
, argv
);
184 ::boost::unit_test::framework::clear();
185 dyn_lib::close( test_lib_handle
);
189 catch( rt::logic_error
const& ex
) {
190 std::cout
<< "Fail to parse command line arguments: " << ex
.msg() << std::endl
;
195 //____________________________________________________________________________//