ios-unity/Libraries/external/baselib/Include/C/Baselib_DynamicLibrary.h
2023-02-10 15:13:26 +08:00

129 lines
5.7 KiB
C

#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