123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- #pragma once
- // Baselib Dynamic Library.
- // In computing, a dynamic linker is the part of an operating system that loads and links
- // the shared libraries needed by an executable when it is executed (at "run time"),
- // by copying the content of libraries from persistent storage to RAM, filling jump tables and
- // relocating pointers. The specific operating system and executable format determine how
- // the dynamic linker functions and how it is implemented.
- //
- // "Dynamic linker", Wikipedia: The Free Encyclopedia
- // https://en.wikipedia.org/w/index.php?title=Dynamic_linker&oldid=935827444
- //
- // Platform specific gotchas:
- // - On Posix/Darwin based platforms, if executable/library has import entries,
- // as for importing functions from .so's/.dylib's at executable/library open time,
- // Baselib_DynamicLibrary_GetFunction is able to return them as well.
- // This is because of ELF/Mach-O format limitations.
- // - On Posix/Darwin based platforms, to be able to query symbols in an executable
- // they must be made visible via --external-dynamic and -external_dynamic flags respectively.
- // Some linkers have an option to make specific symbols visible.
- // - Emscripten limitations are detailed in
- // https://github.com/emscripten-core/emscripten/wiki/Linking
- // - On some platforms dynamic linker doesn't load downstream dependencies.
- // For example if library A imports a symbol from library B,
- // and this is passed to the compiler/linker at compilation step,
- // on most platforms it will generate load entries inside library A to load library B,
- // so if you load library A then library B will be loaded for you by the dynamic linker.
- // But on some platforms, you have to load library B first, and then library A.
- #include "Baselib_ErrorState.h"
- #ifdef __cplusplus
- BASELIB_C_INTERFACE
- {
- #endif
- typedef struct Baselib_DynamicLibrary_Handle { intptr_t handle; } Baselib_DynamicLibrary_Handle;
- // values in range from 0 inclusive to -5 are valid handles on some platforms
- static const Baselib_DynamicLibrary_Handle Baselib_DynamicLibrary_Handle_Invalid = { -100 };
- #include <C/Baselib_DynamicLibrary.inl.h>
- // Open a dynamic library.
- //
- // Dynamic libraries are reference counted, so if the same library is loaded again
- // with Baselib_DynamicLibrary_OpenUtf8/Baselib_DynamicLibrary_OpenUtf16, the same file handle is returned.
- // It is also possible to load two different libraries containing two different functions that have the same name.
- //
- // Please note that additional error information should be retrieved via error state explain and be presented to the end user.
- // This is needed to improve ergonomics of debugging library loading issues.
- //
- // \param pathnameUtf8 Library file to be opened.
- // If relative pathname is provided, platform library search rules are applied (if any).
- // If nullptr is passed, Baselib_ErrorCode_InvalidArgument will be risen.
- //
- // Possible error codes:
- // - Baselib_ErrorCode_FailedToOpenDynamicLibrary: Unable to open requested dynamic library.
- // - Baselib_ErrorCode_NotSupported: This feature is not supported on the current platform.
- BASELIB_API Baselib_DynamicLibrary_Handle Baselib_DynamicLibrary_OpenUtf8(
- const char* pathnameUtf8,
- Baselib_ErrorState* errorState
- );
- // Open a dynamic library.
- // Functionally identical to Baselib_DynamicLibrary_OpenUtf8, but accepts UTF-16 path instead.
- BASELIB_API Baselib_DynamicLibrary_Handle Baselib_DynamicLibrary_OpenUtf16(
- const baselib_char16_t* pathnameUtf16,
- Baselib_ErrorState* errorState
- );
- // Return a handle that can be used to query functions in the program's scope.
- // Must be closed via Baselib_DynamicLibrary_Close.
- //
- // Possible error codes:
- // - Baselib_ErrorCode_NotSupported: This feature is not supported on the current platform.
- BASELIB_API Baselib_DynamicLibrary_Handle Baselib_DynamicLibrary_OpenProgramHandle(
- Baselib_ErrorState* errorState
- );
- // Convert native handle into baselib handle without changing the dynamic library ref counter.
- //
- // Provided handle should be closed either via Baselib_DynamicLibrary_Close or other means.
- // The caller is responsible for closing the handle once done with it.
- // Other corresponding resources should be closed by other means.
- //
- // \param handle Platform defined native handle.
- // \param type Platform defined native handle type from Baselib_DynamicLibrary_NativeHandleType enum.
- // If unsupported type is passed, will return Baselib_DynamicLibrary_Handle_Invalid.
- //
- // \returns Baselib_DynamicLibrary_Handle handle.
- BASELIB_API Baselib_DynamicLibrary_Handle Baselib_DynamicLibrary_FromNativeHandle(
- uint64_t handle,
- uint32_t type,
- Baselib_ErrorState* errorState
- );
- // Lookup a function in a dynamic library.
- //
- // \param handle Library handle.
- // If Baselib_DynamicLibrary_Handle_Invalid is passed, Baselib_ErrorCode_InvalidArgument will be risen.
- // \param functionName Function name to look for.
- // If nullptr is passed, Baselib_ErrorCode_InvalidArgument will be risen.
- //
- // \returns pointer to the function (can be NULL for symbols mapped to NULL).
- //
- // Possible error codes:
- // - Baselib_ErrorCode_FunctionNotFound: Requested function was not found.
- BASELIB_API void* Baselib_DynamicLibrary_GetFunction(
- Baselib_DynamicLibrary_Handle handle,
- const char* functionName,
- Baselib_ErrorState* errorState
- );
- // Close a dynamic library.
- //
- // Decreases reference counter, if it becomes zero, closes the library.
- // If system api will return an error during this operation, the process will be aborted.
- //
- // \param handle Library handle.
- // If Baselib_DynamicLibrary_Handle_Invalid is passed, function is no-op.
- BASELIB_API void Baselib_DynamicLibrary_Close(
- Baselib_DynamicLibrary_Handle handle
- );
- #if __cplusplus
- }
- #endif
|