Counter Strike : Global Offensive Source Code
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.

136 lines
5.0 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. // This makes it easy to dynamically load a shared library and lookup a
  9. // function in that library.
  10. //
  11. // Usage:
  12. // CDynamicFunction<void (*)(const char *)> MyPuts(libname, "puts");
  13. // if (MyPuts)
  14. // MyPuts("Hello world!");
  15. //
  16. // Please note that this interface does not distinguish between functions and
  17. // data. If you look up a global variable in your shared library, or simply
  18. // mess up the function signature, you'll get a valid pointer and a crash
  19. // if you call it as a function.
  20. #ifndef DYNFUNCTION_H
  21. #define DYNFUNCTION_H
  22. #pragma once
  23. #include "tier0/platform.h"
  24. // The heavy lifting isn't template-specific, so we move it out of the header.
  25. DLL_EXPORT void *VoidFnPtrLookup_Tier0(const char *libname, const char *fn, void *fallback);
  26. template < class FunctionType >
  27. class CDynamicFunction
  28. {
  29. public:
  30. // Construct with a NULL function pointer. You must manually call
  31. // Lookup() before you can call a dynamic function through this interface.
  32. CDynamicFunction() : m_pFn(NULL) {}
  33. // Construct and do a lookup right away. You will need to make sure that
  34. // the lookup actually succeeded, as (libname) might have failed to load
  35. // or (fn) might not exist in it.
  36. CDynamicFunction(const char *libname, const char *fn, FunctionType fallback=NULL) : m_pFn(NULL)
  37. {
  38. Lookup(libname, fn, fallback);
  39. }
  40. // Construct and do a lookup right away. See comments in Lookup() about what (okay) does.
  41. CDynamicFunction(const char *libname, const char *fn, bool &okay, FunctionType fallback=NULL) : m_pFn(NULL)
  42. {
  43. Lookup(libname, fn, okay, fallback);
  44. }
  45. // Load library if necessary, look up symbol. Returns true and sets
  46. // m_pFn on successful lookup, returns false otherwise. If the
  47. // function pointer is already looked up, this return true immediately.
  48. // Use Reset() first if you want to look up the symbol again.
  49. // This function will return false immediately unless (okay) is true.
  50. // This allows you to chain lookups like this:
  51. // bool okay = true;
  52. // x.Lookup(lib, "x", okay);
  53. // y.Lookup(lib, "y", okay);
  54. // z.Lookup(lib, "z", okay);
  55. // if (okay) { printf("All functions were loaded successfully!\n"); }
  56. // If you supply a fallback, it'll be used if the lookup fails (and if
  57. // non-NULL, means this will always return (okay)).
  58. bool Lookup(const char *libname, const char *fn, bool &okay, FunctionType fallback=NULL)
  59. {
  60. if (!okay)
  61. return false;
  62. else if (m_pFn == NULL)
  63. m_pFn = (FunctionType) VoidFnPtrLookup_Tier0(libname, fn, (void *) fallback);
  64. okay = m_pFn != NULL;
  65. return okay;
  66. }
  67. // Load library if necessary, look up symbol. Returns true and sets
  68. // m_pFn on successful lookup, returns false otherwise. If the
  69. // function pointer is already looked up, this return true immediately.
  70. // Use Reset() first if you want to look up the symbol again.
  71. // This function will return false immediately unless (okay) is true.
  72. // If you supply a fallback, it'll be used if the lookup fails (and if
  73. // non-NULL, means this will always return true).
  74. bool Lookup(const char *libname, const char *fn, FunctionType fallback=NULL)
  75. {
  76. bool okay = true;
  77. return Lookup(libname, fn, okay, fallback);
  78. }
  79. // Invalidates the current lookup. Makes the function pointer NULL. You
  80. // will need to call Lookup() before you can call a dynamic function
  81. // through this interface again.
  82. void Reset() { m_pFn = NULL; }
  83. // Force this to be a specific function pointer.
  84. void Force(FunctionType ptr) { m_pFn = ptr; }
  85. // Retrieve the actual function pointer.
  86. FunctionType Pointer() const { return m_pFn; }
  87. operator FunctionType() const { return m_pFn; }
  88. // Can be used to verify that we have an actual function looked up and
  89. // ready to call: if (!MyDynFunc) { printf("Function not found!\n"); }
  90. operator bool () const { return m_pFn != NULL; }
  91. bool operator !() const { return m_pFn == NULL; }
  92. protected:
  93. FunctionType m_pFn;
  94. };
  95. // This is the same as CDynamicFunction, but we made the default constructor
  96. // private, forcing you to do loading/lookup during construction.
  97. // The usage pattern is to have a list of dynamic functions that are
  98. // constructed en masse as part of another class's constructor, with the
  99. // possibility of human error removed (the compiler will complain if you
  100. // forget to initialize one).
  101. template < class FunctionType >
  102. class CDynamicFunctionMustInit : public CDynamicFunction < FunctionType >
  103. {
  104. private: // forbid default constructor.
  105. CDynamicFunctionMustInit() {}
  106. public:
  107. CDynamicFunctionMustInit(const char *libname, const char *fn, FunctionType fallback=NULL)
  108. : CDynamicFunction< FunctionType >(libname, fn, fallback)
  109. {
  110. }
  111. CDynamicFunctionMustInit(const char *libname, const char *fn, bool &okay, FunctionType fallback=NULL)
  112. : CDynamicFunction< FunctionType >(libname, fn, okay, fallback)
  113. {
  114. }
  115. };
  116. #endif // DYNFUNCTION_H