⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dl_call.hpp

📁 用STL的方式封装了WindowsAPI、COM调用、ACE、ATL、MFC、WTL等多种组件
💻 HPP
📖 第 1 页 / 共 5 页
字号:
/* /////////////////////////////////////////////////////////////////////////
 * File:        unixstl/dl/dl_call.hpp
 *
 * Purpose:     Invocation of functions in dynamic libraries.
 *
 * Created:     sometime in 1998
 * Updated:     14th June 2006
 *
 * Home:        http://stlsoft.org/
 *
 * Copyright (c) 1998-2006, Matthew Wilson and Synesis Software
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice, this
 *   list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
 *   any contributors may be used to endorse or promote products derived from
 *   this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * ////////////////////////////////////////////////////////////////////// */


/** \file unixstl/dl/dl_call.hpp
 *
 * \brief [C++ only] Definition of the unixstl::dl_call() function suite.
 *  (\ref group__library__dl "DL" Library.)
 */

#ifndef UNIXSTL_INCL_UNIXSTL_DL_HPP_DL_CALL
#define UNIXSTL_INCL_UNIXSTL_DL_HPP_DL_CALL

#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
# define UNIXSTL_VER_UNIXSTL_DL_HPP_DL_CALL_MAJOR       2
# define UNIXSTL_VER_UNIXSTL_DL_HPP_DL_CALL_MINOR       0
# define UNIXSTL_VER_UNIXSTL_DL_HPP_DL_CALL_REVISION    2
# define UNIXSTL_VER_UNIXSTL_DL_HPP_DL_CALL_EDIT        19
#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */

/* /////////////////////////////////////////////////////////////////////////
 * Includes
 */

#ifndef UNIXSTL_INCL_UNIXSTL_H_UNIXSTL
# include <unixstl/unixstl.h>
#endif /* !UNIXSTL_INCL_UNIXSTL_H_UNIXSTL */
#ifndef UNIXSTL_INCL_UNIXSTL_HPP_EXCEPTIONS
# include <unixstl/exceptions.hpp>
#endif /* !UNIXSTL_INCL_UNIXSTL_HPP_EXCEPTIONS */
#ifndef UNIXSTL_INCL_UNIXSTL_DL_HPP_MODULE
# include <unixstl/dl/module.hpp>
#endif /* !UNIXSTL_INCL_UNIXSTL_D:_HPP_MODULE */
#ifndef STLSOFT_INCL_STLSOFT_HPP_STRING_ACCESS
# include <stlsoft/string_access.hpp>
#endif /* STLSOFT_INCL_STLSOFT_HPP_STRING_ACCESS */
// TODO: Make these includes more specific
#ifndef STLSOFT_INCL_H_STLSOFT_META 
# include <stlsoft_meta.h>
#endif /* !STLSOFT_INCL_H_STLSOFT_META */

/* /////////////////////////////////////////////////////////////////////////
 * Namespace
 */

#ifndef _UNIXSTL_NO_NAMESPACE
# if defined(_STLSOFT_NO_NAMESPACE) || \
     defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
/* There is no stlsoft namespace, so must define ::unixstl */
namespace unixstl
{
# else
/* Define stlsoft::unixstl_project */

namespace stlsoft
{

namespace unixstl_project
{

# endif /* _STLSOFT_NO_NAMESPACE */
#endif /* !_UNIXSTL_NO_NAMESPACE */

/* /////////////////////////////////////////////////////////////////////////
 * Classes
 */

/** \brief Exception thrown when an entry point cannot be located in a
 *   dynamic library.
 *
 * \ingroup group__library__dl
 */
class missing_entry_point_exception
    : public unix_exception
{
/// \name Types
/// @{
public:
    typedef unix_exception                      parent_class_type;
    typedef missing_entry_point_exception       class_type;
private:
    typedef parent_class_type::string_type      string_type;
public:
    typedef parent_class_type::error_code_type  error_code_type;
/// @}

/// \name Construction
/// @{
public:
    /// \brief Constructs an instance of the exception based on the given missing
    /// function name, and Windows error code.
    missing_entry_point_exception(char const *functionName, error_code_type err)
        : parent_class_type(class_type::create_reason_(functionName), err)
    {}
#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
    virtual ~missing_entry_point_exception() stlsoft_throw_0()
    {}
#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
/// @}

// Implementation
private:
    static string_type create_reason_(char const *functionName)
    {
        return "Failed to find procedure \"" + string_type(functionName) + '"';
    }

// Not to be implemented
private:
    class_type &operator =(class_type const &);
};

/* /////////////////////////////////////////////////////////////////////////
 * Traits
 */

/** \brief Traits type that provides a mechanism for declaring specific
 *   types to be compatible with dl_call.
 *
 * \ingroup group__library__dl
 *
 * To specify your type being dl_call()-compatible, simply specialise the
 * traits template as follows (for the notional type <code>MyType</code>):
 *
\htmlonly
<pre>
namespace MyNamespace
{
  class MyType
  {};

} // MyNamespace

namespace unixstl
{
  template <>
  struct is_valid_dl_call_arg<MyNamespace::MyType>
  {
    enum { value = 1 };
  };
} // namespace unixstl
</pre>
\endhtmlonly
 */

template<ss_typename_param_k T>
struct is_valid_dl_call_arg
{
    enum { value = 0 };
};

/** \brief Traits class used by the \ref group__library__dl.
 *
 * \ingroup group__library__dl
 *
 * \note This is a struct, rather than a namespace, because namespaces are
 *        open, and we want this to be closed.
 */
struct dl_call_traits
{
/// \name Member Types
/// @{
public:
    typedef void            (*entry_point_type)(void);
    typedef void            *library_handle_type;
    typedef unixstl::module module_wrapper_type;
/// @}

/// \name Dynamic Library Functions
/// @{
public:
    static entry_point_type get_symbol(library_handle_type hLib, char const *functionName)
    {
        return (dl_call_traits::entry_point_type)::dlsym(hLib, functionName);
    }
/// @}

/// \name Function Descriptor Discrimination
/// @{
public:
/// @}

/// \name Module Discrimination
/// @{
public:
    struct library_is_handle
    {};

    struct library_is_not_handle
    {};
/// @}

};


#if defined(STLSOFT_COMPILER_IS_MSVC) || \
    defined(STLSOFT_COMPILER_IS_GCCx)
inline dl_call_traits::library_is_handle test_library_(dl_call_traits::library_handle_type )
{
    return dl_call_traits::library_is_handle();
}
#else /* ? compiler */
inline dl_call_traits::library_is_handle test_library_(dl_call_traits::library_handle_type const &)
{
    return dl_call_traits::library_is_handle();
}
#endif /* compiler */

template <ss_typename_param_k T>
inline dl_call_traits::library_is_not_handle test_library_(T const &)
{
    return dl_call_traits::library_is_not_handle();
}

/* /////////////////////////////////////////////////////////////////////////
 * Helper functions
 */

inline dl_call_traits::entry_point_type lookup_symbol_(dl_call_traits::library_handle_type hinst, char const *functionName)
{
    dl_call_traits::entry_point_type    fp  =   dl_call_traits::get_symbol(hinst, functionName);

    if(dl_call_traits::entry_point_type() == fp)
    {
        throw unixstl::missing_entry_point_exception(functionName, errno);
    }

    return fp;
}

/* ////////////////////////////////////////////////////////////////////// */

/// \name Invocators
///
/// \ingroup group__library__dl
///
/// These calling convention-specific functions perform the invocation of the
/// given function pointer with the requisite arguments.
/// @{

//[<[STLSOFT-AUTO:DL_CALL-INVOCATORS:BEGIN]>]

// 0 params

template<   ss_typename_param_k R
        >
inline R dl_call_invoke_cdecl(dl_call_traits::entry_point_type fp)
{
    R (STLSOFT_CDECL *pfn)();

    reinterpret_cast<dl_call_traits::entry_point_type&>(pfn) = fp;

    return pfn();
}

// 1 param

template<   ss_typename_param_k R
        ,   ss_typename_param_k A0
        >
inline R dl_call_invoke_cdecl(dl_call_traits::entry_point_type fp, A0 a0)
{
    R (STLSOFT_CDECL *pfn)(A0 a0);

    reinterpret_cast<dl_call_traits::entry_point_type&>(pfn) = fp;

    return pfn(a0);
}

// 2 params

template<   ss_typename_param_k R
        ,   ss_typename_param_k A0
        ,   ss_typename_param_k A1
        >
inline R dl_call_invoke_cdecl(dl_call_traits::entry_point_type fp, A0 a0, A1 a1)
{
    R (STLSOFT_CDECL *pfn)(A0 a0, A1 a1);

    reinterpret_cast<dl_call_traits::entry_point_type&>(pfn) = fp;

    return pfn(a0, a1);
}

// 3 params

template<   ss_typename_param_k R
        ,   ss_typename_param_k A0
        ,   ss_typename_param_k A1
        ,   ss_typename_param_k A2
        >
inline R dl_call_invoke_cdecl(dl_call_traits::entry_point_type fp, A0 a0, A1 a1, A2 a2)
{
    R (STLSOFT_CDECL *pfn)(A0 a0, A1 a1, A2 a2);

    reinterpret_cast<dl_call_traits::entry_point_type&>(pfn) = fp;

    return pfn(a0, a1, a2);
}

// 4 params

template<   ss_typename_param_k R
        ,   ss_typename_param_k A0
        ,   ss_typename_param_k A1
        ,   ss_typename_param_k A2
        ,   ss_typename_param_k A3
        >
inline R dl_call_invoke_cdecl(dl_call_traits::entry_point_type fp, A0 a0, A1 a1, A2 a2, A3 a3)
{
    R (STLSOFT_CDECL *pfn)(A0 a0, A1 a1, A2 a2, A3 a3);

    reinterpret_cast<dl_call_traits::entry_point_type&>(pfn) = fp;

    return pfn(a0, a1, a2, a3);
}

// 5 params

template<   ss_typename_param_k R
        ,   ss_typename_param_k A0

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -