You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

620 lines
20 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: winstl/dl/module.hpp (MWModule.h, ::SynesisWin)
  3. *
  4. * Purpose: Contains the module class.
  5. *
  6. * Created: 30th October 1997
  7. * Updated: 12th August 2010
  8. *
  9. * Thanks to: Pablo Aguilar for the idea of a template-based get_symbol().
  10. *
  11. * Home: http://stlsoft.org/
  12. *
  13. * Copyright (c) 1997-2010, Matthew Wilson and Synesis Software
  14. * All rights reserved.
  15. *
  16. * Redistribution and use in source and binary forms, with or without
  17. * modification, are permitted provided that the following conditions are met:
  18. *
  19. * - Redistributions of source code must retain the above copyright notice, this
  20. * list of conditions and the following disclaimer.
  21. * - Redistributions in binary form must reproduce the above copyright notice,
  22. * this list of conditions and the following disclaimer in the documentation
  23. * and/or other materials provided with the distribution.
  24. * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
  25. * any contributors may be used to endorse or promote products derived from
  26. * this software without specific prior written permission.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  29. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  30. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  31. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  32. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  33. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  34. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  35. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  36. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  37. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  38. * POSSIBILITY OF SUCH DAMAGE.
  39. *
  40. * ////////////////////////////////////////////////////////////////////// */
  41. /** \file winstl/dl/module.hpp
  42. *
  43. * \brief [C++ only] Definition of the unixstl::module class
  44. * (\ref group__library__dl "DL" Library).
  45. */
  46. #ifndef WINSTL_INCL_WINSTL_DL_HPP_MODULE
  47. #define WINSTL_INCL_WINSTL_DL_HPP_MODULE
  48. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  49. # define WINSTL_VER_WINSTL_DL_HPP_MODULE_MAJOR 6
  50. # define WINSTL_VER_WINSTL_DL_HPP_MODULE_MINOR 5
  51. # define WINSTL_VER_WINSTL_DL_HPP_MODULE_REVISION 1
  52. # define WINSTL_VER_WINSTL_DL_HPP_MODULE_EDIT 228
  53. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  54. /* /////////////////////////////////////////////////////////////////////////
  55. * Compatibility
  56. */
  57. /*
  58. */
  59. /* /////////////////////////////////////////////////////////////////////////
  60. * Includes
  61. */
  62. #ifndef WINSTL_INCL_WINSTL_H_WINSTL
  63. # include <winstl/winstl.h>
  64. #endif /* !WINSTL_INCL_WINSTL_H_WINSTL */
  65. #ifndef WINSTL_INCL_WINSTL_ERROR_HPP_WINDOWS_EXCEPTIONS
  66. # include <winstl/error/exceptions.hpp>
  67. #endif /* !WINSTL_INCL_WINSTL_ERROR_HPP_WINDOWS_EXCEPTIONS */
  68. #ifndef STLSOFT_INCL_STLSOFT_SHIMS_ACCESS_HPP_STRING
  69. # include <stlsoft/shims/access/string.hpp>
  70. #endif /* !STLSOFT_INCL_STLSOFT_SHIMS_ACCESS_HPP_STRING */
  71. #ifndef WINSTL_INCL_WINSTL_FILESYSTEM_HPP_FILE_PATH_BUFFER
  72. # include <winstl/filesystem/file_path_buffer.hpp>
  73. #endif /* !WINSTL_INCL_WINSTL_FILESYSTEM_HPP_FILE_PATH_BUFFER */
  74. #ifndef WINSTL_INCL_WINSTL_SYSTEM_HPP_SYSTEM_TRAITS
  75. # include <winstl/system/system_traits.hpp>
  76. #endif /* !WINSTL_INCL_WINSTL_SYSTEM_HPP_SYSTEM_TRAITS */
  77. /* /////////////////////////////////////////////////////////////////////////
  78. * Namespace
  79. */
  80. #ifndef _WINSTL_NO_NAMESPACE
  81. # if defined(_STLSOFT_NO_NAMESPACE) || \
  82. defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  83. /* There is no stlsoft namespace, so must define ::winstl */
  84. namespace winstl
  85. {
  86. # else
  87. /* Define stlsoft::winstl_project */
  88. namespace stlsoft
  89. {
  90. namespace winstl_project
  91. {
  92. # endif /* _STLSOFT_NO_NAMESPACE */
  93. #endif /* !_WINSTL_NO_NAMESPACE */
  94. /* /////////////////////////////////////////////////////////////////////////
  95. * Classes
  96. */
  97. /** \brief Class for manipulating dynamically loaded libraries
  98. *
  99. * \ingroup group__library__dl
  100. */
  101. class module
  102. {
  103. public:
  104. /// \brief The handle type
  105. typedef HINSTANCE module_handle_type;
  106. /// \brief The handle type
  107. ///
  108. /// \note This member type is required to make it compatible with
  109. /// the STLSoft get_module_handle access shim
  110. typedef HINSTANCE handle_type;
  111. /// \brief The class type
  112. typedef module class_type;
  113. /// \brief The entry point type
  114. typedef void (*proc_pointer_type)();
  115. private:
  116. typedef void (*degenerate_feedback_proc_type)();
  117. typedef void (*untyped_feedback_proc_type)(void const*, handle_type, void*);
  118. public:
  119. typedef handle_type resource_type;
  120. /// \name Construction
  121. /// @{
  122. public:
  123. /// \brief Constructs by loading the named module
  124. ///
  125. /// \param moduleName The file name of the executable module to be loaded.
  126. ///
  127. /// \note If exception-handling is being used, then this throws a
  128. /// \link winstl::windows_exception windows_exception\endlink
  129. /// if the module cannot be loaded
  130. ss_explicit_k module(ws_char_a_t const* moduleName);
  131. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  132. ss_explicit_k module(ws_char_a_t const* moduleName, void (*pfn)(ws_char_a_t const*, handle_type, void*), void* param);
  133. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  134. /// \brief Constructs by loading the named module
  135. ///
  136. /// \param moduleName The file name of the executable module to be loaded.
  137. ///
  138. /// \note If exception-handling is being used, then this throws a
  139. /// \link winstl::windows_exception windows_exception\endlink
  140. /// if the module cannot be loaded
  141. ss_explicit_k module(ws_char_w_t const* moduleName);
  142. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  143. ss_explicit_k module(ws_char_w_t const* moduleName, void (*pfn)(ws_char_w_t const*, handle_type, void*), void* param);
  144. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  145. #if defined(STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT) && \
  146. ( !defined(STLSOFT_COMPILER_IS_MSVC) || \
  147. _MSC_VER >= 1200)
  148. /// \brief Constructs by loading the named module
  149. ///
  150. /// \param moduleName The file name of the executable module to be
  151. /// loaded. The argument may be of any type for which the
  152. /// \ref group__concept__shim__string_access "string access shim"
  153. /// stlsoft::c_str_ptr is defined.
  154. ///
  155. /// \note If exception-handling is being used, then this throws a
  156. /// \link winstl::windows_exception windows_exception\endlink
  157. /// if the module cannot be loaded
  158. template <ss_typename_param_k S>
  159. ss_explicit_k module(S const& moduleName)
  160. : m_hmodule(load(moduleName))
  161. , m_param(NULL)
  162. , m_proc(NULL)
  163. {
  164. # ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  165. if(NULL == m_hmodule)
  166. {
  167. STLSOFT_THROW_X(windows_exception("Cannot load module", ::GetLastError()));
  168. }
  169. # endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  170. }
  171. #endif /* STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT */
  172. /// \brief Constructs by taking ownership of the given handle
  173. ///
  174. /// \note If exception-handling is being used, then this throws a
  175. /// \link winstl::windows_exception windows_exception\endlink
  176. /// if the handle is NULL.
  177. ss_explicit_k module(module_handle_type hmodule);
  178. /// \brief Copy constructor
  179. ///
  180. /// \note Both copies hold independent handles to the underlying module.
  181. module(class_type const& rhs);
  182. /// \brief Closes the module handle
  183. ~module() stlsoft_throw_0();
  184. /// @}
  185. /// \name Static operations
  186. /// @{
  187. public:
  188. /// \brief Loads the named module, returning its handle, which the
  189. /// caller must close with unload().
  190. ///
  191. /// \param moduleName The file name of the executable module to be loaded.
  192. ///
  193. /// \return The module handle, or NULL if no matching module found.
  194. static module_handle_type load(ws_char_a_t const* moduleName);
  195. /// \brief Loads the named module, returning its handle, which the
  196. /// caller must close with unload().
  197. ///
  198. /// \param moduleName The file name of the executable module to be loaded.
  199. ///
  200. /// \return The module handle, or NULL if no matching module found.
  201. static module_handle_type load(ws_char_w_t const* moduleName);
  202. #if defined(STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT) && \
  203. ( !defined(STLSOFT_COMPILER_IS_MSVC) || \
  204. _MSC_VER >= 1200)
  205. /// \brief Loads the named module, returning its handle, which the
  206. /// caller must close with unload().
  207. ///
  208. /// \param moduleName The file name of the executable module to be
  209. /// loaded. The argument may be of any type for which the
  210. /// \ref group__concept__shim__string_access "string access shim"
  211. /// stlsoft::c_str_ptr is defined.
  212. ///
  213. /// \return The module handle, or NULL if no matching module found.
  214. template <ss_typename_param_k S>
  215. static module_handle_type load(S const& moduleName)
  216. {
  217. return class_type::load(stlsoft_ns_qual(c_str_ptr)(moduleName));
  218. }
  219. #endif /* STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT */
  220. /// \brief Closes the given module handle
  221. static void unload(module_handle_type hmodule) stlsoft_throw_0();
  222. /// \brief Looks up a named symbol from the given module.
  223. ///
  224. /// \return A pointer to the named symbol, or NULL if not found.
  225. static proc_pointer_type get_symbol(module_handle_type hmodule, ws_char_a_t const* symbolName);
  226. /// \brief Looks up a symbol by ordinal from the given module.
  227. ///
  228. /// \return A pointer to the named symbol, or NULL if not found.
  229. static proc_pointer_type get_symbol(module_handle_type hmodule, ws_uint32_t symbolOrdinal);
  230. #if defined(STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT) && \
  231. ( !defined(STLSOFT_COMPILER_IS_MSVC) || \
  232. _MSC_VER >= 1200)
  233. /// \brief Looks up a named symbol from the given module into a typed function pointer variable.
  234. ///
  235. /// \return A pointer to the named symbol, or NULL if not found.
  236. template <ss_typename_param_k F>
  237. static proc_pointer_type get_symbol(module_handle_type hmodule, ws_char_a_t const* symbolName, F &f)
  238. {
  239. proc_pointer_type proc = class_type::get_symbol(hmodule, symbolName);
  240. f = reinterpret_cast<F>(proc);
  241. return proc;
  242. }
  243. /// \brief Looks up a symbol by ordinal from the given module into a typed function pointer variable.
  244. ///
  245. /// \return A pointer to the named symbol, or NULL if not found.
  246. template <ss_typename_param_k F>
  247. static proc_pointer_type get_symbol(module_handle_type hmodule, ws_uint32_t symbolOrdinal, F &f)
  248. {
  249. proc_pointer_type proc = class_type::get_symbol(hmodule, symbolOrdinal);
  250. f = reinterpret_cast<F>(proc);
  251. return proc;
  252. }
  253. #endif /* STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT */
  254. /// @}
  255. /// \name Operations
  256. /// @{
  257. public:
  258. /// \brief Closes the module handle
  259. void unload() stlsoft_throw_0();
  260. /// \brief Yields the module handle to the caller
  261. module_handle_type detach();
  262. /// @}
  263. /// \name Lookup Operations
  264. /// @{
  265. public:
  266. /// \brief Looks up a named symbol.
  267. ///
  268. /// \return A pointer to the named symbol, or NULL if not found.
  269. proc_pointer_type get_symbol(ws_char_a_t const* symbolName);
  270. /// \brief Looks up a symbol by ordinal.
  271. ///
  272. /// \return A pointer to the named symbol, or NULL if not found.
  273. proc_pointer_type get_symbol(ws_uint32_t symbolOrdinal);
  274. #if defined(STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT) && \
  275. ( !defined(STLSOFT_COMPILER_IS_MSVC) || \
  276. _MSC_VER >= 1200)
  277. /// \brief Looks up a named symbol into a typed function pointer variable.
  278. ///
  279. /// \return A pointer to the named symbol, or NULL if not found.
  280. template <ss_typename_param_k F>
  281. proc_pointer_type get_symbol(ws_char_a_t const* symbolName, F &f)
  282. {
  283. return class_type::get_symbol(m_hmodule, symbolName, f);
  284. }
  285. /// \brief Looks up a symbol by ordinal into a typed function pointer variable.
  286. ///
  287. /// \return A pointer to the named symbol, or NULL if not found.
  288. template <ss_typename_param_k F>
  289. proc_pointer_type get_symbol(ws_uint32_t symbolOrdinal, F &f)
  290. {
  291. return class_type::get_symbol(m_hmodule, symbolOrdinal, f);
  292. }
  293. #endif /* STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT */
  294. /// @}
  295. /// \name Accessors
  296. /// @{
  297. public:
  298. /// \brief Provides access to the underlying module handle
  299. module_handle_type get_module_handle() const;
  300. /// \brief Provides access to the underlying module handle
  301. module_handle_type get() const;
  302. /// @}
  303. /// \name Implementation
  304. /// @{
  305. private:
  306. static module_handle_type load(ws_char_a_t const* moduleName, void (*pfn)(ws_char_a_t const*, handle_type, void*), void* param);
  307. static module_handle_type load(ws_char_w_t const* moduleName, void (*pfn)(ws_char_w_t const*, handle_type, void*), void* param);
  308. static void unload(module_handle_type hmodule, degenerate_feedback_proc_type, void* param) /* stlsoft_throw_0() */;
  309. /// @}
  310. /// \name Member Variables
  311. /// @{
  312. private:
  313. module_handle_type m_hmodule;
  314. void* const m_param;
  315. const degenerate_feedback_proc_type m_proc;
  316. /// @}
  317. /// \name Not to be implemented
  318. /// @{
  319. private:
  320. class_type& operator =(class_type const&);
  321. /// @}
  322. };
  323. /* /////////////////////////////////////////////////////////////////////////
  324. * Access shims
  325. */
  326. /** \brief Returns the module handle for the given module
  327. *
  328. * \ingroup group__concept__shim__module_attribute
  329. */
  330. inline HINSTANCE get_module_handle(winstl_ns_qual(module) const& m)
  331. {
  332. return m.get_module_handle();
  333. }
  334. /* /////////////////////////////////////////////////////////////////////////
  335. * Unit-testing
  336. */
  337. #ifdef STLSOFT_UNITTEST
  338. # include "./unittest/module_unittest_.h"
  339. #endif /* STLSOFT_UNITTEST */
  340. /* /////////////////////////////////////////////////////////////////////////
  341. * Implementation
  342. */
  343. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  344. inline module::module(ws_char_a_t const* moduleName)
  345. : m_hmodule(load(moduleName))
  346. , m_param(NULL)
  347. , m_proc(NULL)
  348. {
  349. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  350. if(NULL == m_hmodule)
  351. {
  352. STLSOFT_THROW_X(windows_exception("Cannot load module", ::GetLastError()));
  353. }
  354. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  355. }
  356. inline module::module(ws_char_a_t const* moduleName, void (*pfn)(ws_char_a_t const*, handle_type, void*), void* param)
  357. : m_hmodule(load(moduleName, pfn, param))
  358. , m_param(param)
  359. , m_proc(reinterpret_cast<degenerate_feedback_proc_type>(pfn))
  360. {
  361. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  362. if(NULL == m_hmodule)
  363. {
  364. STLSOFT_THROW_X(windows_exception("Cannot load module", ::GetLastError()));
  365. }
  366. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  367. }
  368. inline module::module(ws_char_w_t const* moduleName)
  369. : m_hmodule(load(moduleName))
  370. , m_param(NULL)
  371. , m_proc(NULL)
  372. {
  373. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  374. if(NULL == m_hmodule)
  375. {
  376. STLSOFT_THROW_X(windows_exception("Cannot load module", ::GetLastError()));
  377. }
  378. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  379. }
  380. inline module::module(ws_char_w_t const* moduleName, void (*pfn)(ws_char_w_t const*, handle_type, void*), void* param)
  381. : m_hmodule(load(moduleName, pfn, param))
  382. , m_param(param)
  383. , m_proc(reinterpret_cast<degenerate_feedback_proc_type>(pfn))
  384. {
  385. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  386. if(NULL == m_hmodule)
  387. {
  388. STLSOFT_THROW_X(windows_exception("Cannot load module", ::GetLastError()));
  389. }
  390. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  391. }
  392. inline module::module(module::module_handle_type hmodule)
  393. : m_hmodule(hmodule)
  394. , m_param(NULL)
  395. , m_proc(NULL)
  396. {
  397. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  398. if(NULL == m_hmodule)
  399. {
  400. STLSOFT_THROW_X(windows_exception("Cannot load module", ::GetLastError()));
  401. }
  402. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  403. }
  404. inline module::module(module const& rhs)
  405. : m_param(NULL)
  406. , m_proc(NULL)
  407. {
  408. if(NULL == rhs.get_module_handle())
  409. {
  410. m_hmodule = NULL;
  411. }
  412. else
  413. {
  414. basic_file_path_buffer<ws_char_a_t> buffer;
  415. ws_size_t cch = system_traits<ws_char_a_t>::get_module_filename(rhs.get_module_handle(), &buffer[0], buffer.size());
  416. if(0 == cch)
  417. {
  418. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  419. STLSOFT_THROW_X(windows_exception("Cannot get module path", ::GetLastError()));
  420. #else /* STLSOFT_CF_EXCEPTION_SUPPORT */
  421. m_hmodule = NULL;
  422. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  423. }
  424. else
  425. {
  426. m_hmodule = load(buffer.data());
  427. }
  428. }
  429. }
  430. inline module::~module() stlsoft_throw_0()
  431. {
  432. unload();
  433. }
  434. inline void module::unload() stlsoft_throw_0()
  435. {
  436. if(NULL != m_hmodule)
  437. {
  438. if(NULL != m_proc)
  439. {
  440. class_type::unload(m_hmodule, m_proc, m_param);
  441. }
  442. else
  443. {
  444. class_type::unload(m_hmodule);
  445. }
  446. m_hmodule = NULL;
  447. }
  448. }
  449. inline module::module_handle_type module::detach()
  450. {
  451. module_handle_type h;
  452. h = m_hmodule;
  453. m_hmodule = NULL;
  454. return h;
  455. }
  456. inline /* static */ module::module_handle_type module::load(ws_char_a_t const* moduleName)
  457. {
  458. return ::LoadLibraryA(moduleName);
  459. }
  460. inline /* static */ module::module_handle_type module::load(ws_char_a_t const* moduleName, void (*pfn)(ws_char_a_t const*, handle_type, void*), void* param)
  461. {
  462. HINSTANCE hinst = ::LoadLibraryA(moduleName);
  463. if(NULL != pfn)
  464. {
  465. (*pfn)(moduleName, hinst, param);
  466. }
  467. return hinst;
  468. }
  469. inline /* static */ module::module_handle_type module::load(ws_char_w_t const* moduleName)
  470. {
  471. return ::LoadLibraryW(moduleName);
  472. }
  473. inline /* static */ void module::unload(module::module_handle_type hmodule) stlsoft_throw_0()
  474. {
  475. if(NULL != hmodule)
  476. {
  477. ::FreeLibrary(hmodule);
  478. }
  479. }
  480. inline /* static */ void module::unload(module::module_handle_type hmodule, module::degenerate_feedback_proc_type pfn, void* param) /* stlsoft_throw_0() */
  481. {
  482. if(NULL != hmodule)
  483. {
  484. if(NULL != pfn)
  485. {
  486. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  487. try
  488. {
  489. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  490. untyped_feedback_proc_type fn = reinterpret_cast<untyped_feedback_proc_type>(pfn);
  491. (*fn)(NULL, hmodule, param);
  492. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  493. }
  494. catch(...)
  495. {
  496. STLSOFT_MESSAGE_ASSERT("Module feedback procedure threw an exception", 0);
  497. throw; // This will, hopefully, precipitate unexpected()
  498. }
  499. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  500. }
  501. ::FreeLibrary(hmodule);
  502. }
  503. }
  504. inline /* static */ module::proc_pointer_type module::get_symbol(module::module_handle_type hmodule, ws_char_a_t const* symbolName)
  505. {
  506. return reinterpret_cast<proc_pointer_type>(GetProcAddress(hmodule, symbolName));
  507. }
  508. inline /* static */ module::proc_pointer_type module::get_symbol(module::module_handle_type hmodule, ws_uint32_t symbolOrdinal)
  509. {
  510. ws_char_a_t const* s = MAKEINTRESOURCEA(symbolOrdinal);
  511. return get_symbol(hmodule, s);
  512. }
  513. inline module::proc_pointer_type module::get_symbol(ws_char_a_t const* symbolName)
  514. {
  515. return get_symbol(m_hmodule, symbolName);
  516. }
  517. inline module::proc_pointer_type module::get_symbol(ws_uint32_t symbolOrdinal)
  518. {
  519. return get_symbol(m_hmodule, symbolOrdinal);
  520. }
  521. inline module::module_handle_type module::get_module_handle() const
  522. {
  523. return m_hmodule;
  524. }
  525. inline module::module_handle_type module::get() const
  526. {
  527. return m_hmodule;
  528. }
  529. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  530. /* ////////////////////////////////////////////////////////////////////// */
  531. #ifndef _WINSTL_NO_NAMESPACE
  532. # if defined(_STLSOFT_NO_NAMESPACE) || \
  533. defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  534. } // namespace winstl
  535. # else
  536. } // namespace winstl_project
  537. } // namespace stlsoft
  538. # endif /* _STLSOFT_NO_NAMESPACE */
  539. #endif /* !_WINSTL_NO_NAMESPACE */
  540. /* ////////////////////////////////////////////////////////////////////// */
  541. #endif /* WINSTL_INCL_WINSTL_DL_HPP_MODULE */
  542. /* ///////////////////////////// end of file //////////////////////////// */