dxcapi.use.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. //////////////////////////////////////////////////////////////////////////////
  2. // //
  3. // dxcapi.use.h //
  4. // Copyright (C) Microsoft Corporation. All rights reserved. //
  5. // This file is distributed under the University of Illinois Open Source //
  6. // License. See LICENSE.TXT for details. //
  7. // //
  8. // Provides support for DXC API users. //
  9. // //
  10. ///////////////////////////////////////////////////////////////////////////////
  11. #ifndef __DXCAPI_USE_H__
  12. #define __DXCAPI_USE_H__
  13. #include "dxc/dxcapi.h"
  14. namespace dxc {
  15. // Helper class to dynamically load the dxcompiler or a compatible libraries.
  16. class DxcDllSupport {
  17. protected:
  18. HMODULE m_dll;
  19. DxcCreateInstanceProc m_createFn;
  20. DxcCreateInstance2Proc m_createFn2;
  21. HRESULT InitializeInternal(LPCWSTR dllName, LPCSTR fnName) {
  22. if (m_dll != nullptr) return S_OK;
  23. #ifdef _WIN32
  24. m_dll = LoadLibraryW(dllName);
  25. #else
  26. char nameStr[256];
  27. std::wcstombs(nameStr, dllName, 256);
  28. m_dll = ::dlopen(nameStr, RTLD_LAZY);
  29. #endif
  30. if (m_dll == nullptr) return HRESULT_FROM_WIN32(GetLastError());
  31. #ifdef _WIN32
  32. m_createFn = (DxcCreateInstanceProc)GetProcAddress(m_dll, fnName);
  33. #else
  34. m_createFn = (DxcCreateInstanceProc)::dlsym(m_dll, fnName);
  35. #endif
  36. if (m_createFn == nullptr) {
  37. HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
  38. #ifdef _WIN32
  39. FreeLibrary(m_dll);
  40. #else
  41. ::dlclose(m_dll);
  42. #endif
  43. m_dll = nullptr;
  44. return hr;
  45. }
  46. // Only basic functions used to avoid requiring additional headers.
  47. m_createFn2 = nullptr;
  48. char fnName2[128];
  49. size_t s = strlen(fnName);
  50. if (s < sizeof(fnName2) - 2) {
  51. memcpy(fnName2, fnName, s);
  52. fnName2[s] = '2';
  53. fnName2[s + 1] = '\0';
  54. #ifdef _WIN32
  55. m_createFn2 = (DxcCreateInstance2Proc)GetProcAddress(m_dll, fnName2);
  56. #else
  57. m_createFn2 = (DxcCreateInstance2Proc)::dlsym(m_dll, fnName2);
  58. #endif
  59. }
  60. return S_OK;
  61. }
  62. public:
  63. DxcDllSupport() : m_dll(nullptr), m_createFn(nullptr), m_createFn2(nullptr) {
  64. }
  65. DxcDllSupport(DxcDllSupport&& other) {
  66. m_dll = other.m_dll; other.m_dll = nullptr;
  67. m_createFn = other.m_createFn; other.m_createFn = nullptr;
  68. m_createFn2 = other.m_createFn2; other.m_createFn2 = nullptr;
  69. }
  70. ~DxcDllSupport() {
  71. Cleanup();
  72. }
  73. HRESULT Initialize() {
  74. #ifdef _WIN32
  75. return InitializeInternal(L"dxcompiler.dll", "DxcCreateInstance");
  76. #elif __APPLE__
  77. return InitializeInternal(L"libdxcompiler.dylib", "DxcCreateInstance");
  78. #else
  79. return InitializeInternal(L"libdxcompiler.so", "DxcCreateInstance");
  80. #endif
  81. }
  82. HRESULT InitializeForDll(_In_z_ const wchar_t* dll, _In_z_ const char* entryPoint) {
  83. return InitializeInternal(dll, entryPoint);
  84. }
  85. template <typename TInterface>
  86. HRESULT CreateInstance(REFCLSID clsid, _Outptr_ TInterface** pResult) {
  87. return CreateInstance(clsid, __uuidof(TInterface), (IUnknown**)pResult);
  88. }
  89. HRESULT CreateInstance(REFCLSID clsid, REFIID riid, _Outptr_ IUnknown **pResult) {
  90. if (pResult == nullptr) return E_POINTER;
  91. if (m_dll == nullptr) return E_FAIL;
  92. HRESULT hr = m_createFn(clsid, riid, (LPVOID*)pResult);
  93. return hr;
  94. }
  95. template <typename TInterface>
  96. HRESULT CreateInstance2(IMalloc *pMalloc, REFCLSID clsid, _Outptr_ TInterface** pResult) {
  97. return CreateInstance2(pMalloc, clsid, __uuidof(TInterface), (IUnknown**)pResult);
  98. }
  99. HRESULT CreateInstance2(IMalloc *pMalloc, REFCLSID clsid, REFIID riid, _Outptr_ IUnknown **pResult) {
  100. if (pResult == nullptr) return E_POINTER;
  101. if (m_dll == nullptr) return E_FAIL;
  102. if (m_createFn2 == nullptr) return E_FAIL;
  103. HRESULT hr = m_createFn2(pMalloc, clsid, riid, (LPVOID*)pResult);
  104. return hr;
  105. }
  106. bool HasCreateWithMalloc() const {
  107. return m_createFn2 != nullptr;
  108. }
  109. bool IsEnabled() const {
  110. return m_dll != nullptr;
  111. }
  112. void Cleanup() {
  113. if (m_dll != nullptr) {
  114. m_createFn = nullptr;
  115. m_createFn2 = nullptr;
  116. #ifdef _WIN32
  117. FreeLibrary(m_dll);
  118. #else
  119. ::dlclose(m_dll);
  120. #endif
  121. m_dll = nullptr;
  122. }
  123. }
  124. HMODULE Detach() {
  125. HMODULE hModule = m_dll;
  126. m_dll = nullptr;
  127. return hModule;
  128. }
  129. };
  130. inline DxcDefine GetDefine(_In_ LPCWSTR name, LPCWSTR value) {
  131. DxcDefine result;
  132. result.Name = name;
  133. result.Value = value;
  134. return result;
  135. }
  136. // Checks an HRESULT and formats an error message with the appended data.
  137. void IFT_Data(HRESULT hr, _In_opt_ LPCWSTR data);
  138. void EnsureEnabled(DxcDllSupport &dxcSupport);
  139. void ReadFileIntoBlob(DxcDllSupport &dxcSupport, _In_ LPCWSTR pFileName,
  140. _Outptr_ IDxcBlobEncoding **ppBlobEncoding);
  141. void WriteBlobToConsole(_In_opt_ IDxcBlob *pBlob, DWORD streamType = STD_OUTPUT_HANDLE);
  142. void WriteBlobToFile(_In_opt_ IDxcBlob *pBlob, _In_ LPCWSTR pFileName, _In_ UINT32 textCodePage);
  143. void WriteBlobToHandle(_In_opt_ IDxcBlob *pBlob, _In_ HANDLE hFile, _In_opt_ LPCWSTR pFileName, _In_ UINT32 textCodePage);
  144. void WriteUtf8ToConsole(_In_opt_count_(charCount) const char *pText,
  145. int charCount, DWORD streamType = STD_OUTPUT_HANDLE);
  146. void WriteUtf8ToConsoleSizeT(_In_opt_count_(charCount) const char *pText,
  147. size_t charCount, DWORD streamType = STD_OUTPUT_HANDLE);
  148. void WriteOperationErrorsToConsole(_In_ IDxcOperationResult *pResult,
  149. bool outputWarnings);
  150. void WriteOperationResultToConsole(_In_ IDxcOperationResult *pRewriteResult,
  151. bool outputWarnings);
  152. } // namespace dxc
  153. #endif