lzham_dynamic_lib.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. #pragma once
  2. #define LZHAM_DYNAMIC_LIB 1
  3. #include "lzham.h"
  4. #ifdef _XBOX
  5. #define LZHAM_DLL_FILENAME "lzham_x360.dll"
  6. #define LZHAM_DEBUG_DLL_FILENAME "lzham_x360D.dll"
  7. #else
  8. // FIXME: This stuff should probably be moved to another header.
  9. #if LZHAM_64BIT
  10. #define LZHAM_DLL_FILENAME "lzham_x64.dll"
  11. #define LZHAM_DEBUG_DLL_FILENAME "lzham_x64D.dll"
  12. #else
  13. #define LZHAM_DLL_FILENAME "lzham_x86.dll"
  14. #define LZHAM_DEBUG_DLL_FILENAME "lzham_x86D.dll"
  15. #endif
  16. #endif
  17. #ifdef __cplusplus
  18. // Simple helper class that demonstrates how to dynamically load the LZHAM DLL.
  19. // The load() method loads the DLL, then initializes the member function pointers in ilzham by calling GetProcAddress() on all exported API's defined in lzham_exports.inc.
  20. class lzham_dll_loader : public ilzham
  21. {
  22. lzham_dll_loader(const lzham_dll_loader &other);
  23. lzham_dll_loader& operator= (const lzham_dll_loader &rhs);
  24. public:
  25. lzham_dll_loader() : ilzham(), m_handle(NULL), m_win32_error(S_OK)
  26. {
  27. }
  28. virtual ~lzham_dll_loader()
  29. {
  30. unload();
  31. }
  32. enum
  33. {
  34. cErrorMissingExport = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x201),
  35. cErrorUnsupportedDLLVersion = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x202),
  36. };
  37. // Assumes LZHAM DLL is in the same path as the executable.
  38. #if defined(_XBOX) || defined(_MSC_VER)
  39. static void create_module_path(char *pModulePath, int size_in_chars, bool debug_dll)
  40. {
  41. #ifdef _XBOX
  42. char *buf = "D:\\unused.xex";
  43. #else
  44. char buf[MAX_PATH];
  45. GetModuleFileNameA(NULL, buf, sizeof(buf));
  46. #endif
  47. char drive_buf[_MAX_DRIVE], dir_buf[_MAX_DIR], filename_buf[_MAX_FNAME], ext_buf[_MAX_EXT];
  48. _splitpath_s(buf, drive_buf, _MAX_DRIVE, dir_buf, _MAX_DIR, NULL, 0, NULL, 0);
  49. _splitpath_s(debug_dll ? LZHAM_DEBUG_DLL_FILENAME : LZHAM_DLL_FILENAME, NULL, 0, NULL, 0, filename_buf, _MAX_FNAME, ext_buf, _MAX_EXT);
  50. _makepath_s(pModulePath, size_in_chars, drive_buf, dir_buf, filename_buf, ext_buf);
  51. }
  52. #else
  53. static void create_module_path(char *pModulePath, int size_in_chars, bool debug_dll)
  54. {
  55. strcpy(pModulePath, debug_dll ? LZHAM_DEBUG_DLL_FILENAME : LZHAM_DLL_FILENAME);
  56. }
  57. #endif
  58. virtual bool load()
  59. {
  60. HRESULT hres = load(NULL);
  61. return S_OK == hres;
  62. }
  63. HRESULT load(const char* pModulePath)
  64. {
  65. unload();
  66. char buf[MAX_PATH];
  67. if (!pModulePath)
  68. {
  69. create_module_path(buf, sizeof(buf), false);
  70. pModulePath = buf;
  71. }
  72. m_win32_error = S_OK;
  73. m_handle = LoadLibraryA(pModulePath);
  74. if (NULL == m_handle)
  75. {
  76. m_win32_error = HRESULT_FROM_WIN32(GetLastError());
  77. return m_win32_error;
  78. }
  79. struct
  80. {
  81. const char* pName;
  82. void** pFunc_ptr;
  83. }
  84. funcs[] =
  85. {
  86. #define LZHAM_DLL_FUNC_NAME(x) { #x, (void**)&x },
  87. #include "lzham_exports.inc"
  88. #undef LZHAM_DLL_FUNC_NAME
  89. };
  90. const int cNumFuncs = sizeof(funcs) / sizeof(funcs[0]);
  91. for (int i = 0; i < cNumFuncs; i++)
  92. {
  93. #ifdef _XBOX
  94. if ((*funcs[i].pFunc_ptr = GetProcAddress(m_handle, (LPCSTR)(i + 1))) == NULL)
  95. #else
  96. if ((*funcs[i].pFunc_ptr = (void*)GetProcAddress(m_handle, funcs[i].pName)) == NULL)
  97. #endif
  98. {
  99. unload();
  100. m_win32_error = cErrorMissingExport;
  101. return m_win32_error;
  102. }
  103. }
  104. int dll_ver = lzham_get_version();
  105. // Ensure DLL's major version is the expected version.
  106. if ((dll_ver >> 8U) != (LZHAM_DLL_VERSION >> 8U))
  107. {
  108. unload();
  109. m_win32_error = cErrorUnsupportedDLLVersion;
  110. return m_win32_error;
  111. }
  112. return S_OK;
  113. }
  114. virtual void unload()
  115. {
  116. if (m_handle)
  117. {
  118. FreeLibrary(m_handle);
  119. m_handle = NULL;
  120. }
  121. clear();
  122. m_win32_error = S_OK;
  123. }
  124. virtual bool is_loaded() { return m_handle != NULL; }
  125. HRESULT get_last_win32_error() { return m_win32_error; }
  126. private:
  127. HMODULE m_handle;
  128. HRESULT m_win32_error;
  129. };
  130. #endif // #ifdef __cplusplus