#include <j.hpp> #if (!IS_WINDOWS) #include <dlfcn.h> #endif #include <j/lang/string.hpp> #include <j/lang/dl.hpp> namespace j { namespace lang { /** * Dl を構築します。 */ Dl::Dl(const String &fileName) noexcept { #if (IS_WINDOWS) handle = ::LoadLibraryEx(fileName); #else handle = ::dlopen(fileName, RTLD_LAZY); #endif // TODO : handle == 0 の場合エラー } /** * Dl のコピーコンストラクタ。 * * @param dl コピー元オブジェクト */ Dl::Dl(const Dl &dl) noexcept : Object(dl), handle(dl.handle) { /* NOP */ } /** * Dl のムーブコンストラクタ。 * * @param dl ムーブ元オブジェクト */ Dl::Dl(Dl &&dl) noexcept : Object(std::move(dl)), handle(std::move(dl.handle)) { /* NOP */ } // デストラクタ Dl::~Dl() noexcept { #if (IS_WINDOWS) ::FreeLibrary(handle); #else ::dlclose(handle); #endif } /** * コピー代入演算子。 * コピーして代入します。 * * @param dl コピー元オブジェクト * @return 本オブジェクトへの参照 */ Dl &Dl::operator=(const Dl &dl) noexcept { if (this != &dl) { Object::operator=(dl); handle = dl.handle; } return *this; } /** * ムーブ代入演算子。 * * @param dl ムーブ元オブジェクト * @return 本オブジェクトへの参照 */ Dl &Dl::operator=(Dl &&dl) noexcept { if (this != &dl) { Object::operator=(std::move(dl)); handle = std::move(dl.handle); handle = nullptr; } return *this; } /** * 本オブジェクトの文字列表現を返します。 * * @return 本オブジェクトの文字列表現 */ String Dl::toString() const noexcept { return Object::toString(); } /** * 指定されたシンボルがロードされたメモリのアドレスを返します。 * * @code * typedef USHORT (WINAPI *RtlCaptureStackBackTraceDef) (ULONG framesToSkip, ULOLNG framesToCapture, PVOID *backTrace, PULONG backTraceHash); * Dl dl("kernel32.dll"); * RtlCaptureStackBackTraceDef RtlCaptureStackBackTrace = reinterpret_cast<RtlCaptureStackBackTraceDef>(dl.sym("RtlCaptureStackBackTrace")); * void* buffer[64]; * int cnt = RtlCaptureStackBackTrace(0, 64, buffer, 0); * for (int i = 0; i < cnt; i++) * { * std::cout << buffer[i] << std::endl; * } * @endcode * * @param symbol シンボル名 * @return シンボルのアドレス */ dl_func_t Dl::sym(const String &symbol) { #if (IS_WINDOWS) return ::GetProcAddress(handle, symbol); #else return ::dlsym(handle, symbol); #endif } } // namespace lang } // namespace j