{"id":13805287,"url":"https://github.com/BindBC/bindbc-loader","last_synced_at":"2025-05-13T19:30:37.166Z","repository":{"id":56868612,"uuid":"124233500","full_name":"BindBC/bindbc-loader","owner":"BindBC","description":"A cross-platform, @nogc, nothrow, and BetterC compatible shared library loading API. (Mirror)","archived":false,"fork":false,"pushed_at":"2025-01-28T13:37:19.000Z","size":45,"stargazers_count":25,"open_issues_count":0,"forks_count":8,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-28T14:33:37.717Z","etag":null,"topics":["dlang"],"latest_commit_sha":null,"homepage":"https://git.sleeping.town/BindBC/bindbc-loader","language":"D","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/BindBC.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE_1_0.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-03-07T12:33:57.000Z","updated_at":"2025-01-28T13:38:30.000Z","dependencies_parsed_at":"2024-03-01T17:52:59.993Z","dependency_job_id":null,"html_url":"https://github.com/BindBC/bindbc-loader","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BindBC%2Fbindbc-loader","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BindBC%2Fbindbc-loader/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BindBC%2Fbindbc-loader/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BindBC%2Fbindbc-loader/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BindBC","download_url":"https://codeload.github.com/BindBC/bindbc-loader/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254012942,"owners_count":21999339,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dlang"],"created_at":"2024-08-04T01:00:59.649Z","updated_at":"2025-05-13T19:30:37.140Z","avatar_url":"https://github.com/BindBC.png","language":"D","funding_links":[],"categories":["Game Bindings"],"sub_categories":["XML"],"readme":"# [BindBC-Loader](https://git.sleeping.town/BindBC/bindbc-loader)\nThis library contains the cross-platform shared library loading API used by the BindBC packages in their dynamic binding configurations. It is compatible with BetterC, `@nogc`, and `nothrow`, and intended as a replacement for [DerelictUtil](https://github.com/DerelictOrg/DerelictUtil), which does not provide the same level of compatibility.\n\nThe dynamic configuration of each official BindBC package implements its own public load function, which calls into the BindBC-Loader API to load function pointers from the appropriate shared library. BindBC-Loader is only for dynamic bindings, which have no link-time dependency on the bound library.\n\nUsers of packages dependent on BindBC-Loader need not be concerned with its configuration or the loader API. For such users, only the error handling API is of relevance. Anyone implementing a shared library loader on top of BindBC-Loader should be familiar with the entire public API and its configuration.\n\n| Table of Contents |\n|-------------------|\n|[License](#license)|\n|[Error handling](#error-handling)|\n|[Configurations](#configurations)|\n|[Default Windows search path](#default-windows-search-path)|\n\n## License\n\nBindBC-Loader\u0026mdash;as well as every other library in the [BindBC project](https://github.com/BindBC)\u0026mdash;is licensed under the [Boost Software License](https://www.boost.org/LICENSE_1_0.txt).\n\n## Error handling\nBindBC-Loader does not use exceptions. This decision was made for easier maintenance of the BetterC compatibility, and to provide a common API between both configurations. An application using a dependent package can check for errors consistently when compiling with and without BetterC.\n\nThe `errors()` function is most relevant to end-users of dependant libraries. `errorCount()`, and `resetErrors()` may also be occasionally useful. All three are found in the `bindbc.loader.sharedlib` module.\n\nErrors are usually generated in two cases:\n1. When a shared library cannot be loaded, usually because the shared library file cannot be found.\n2. When a symbol in the library fails to load.\n\nMultiple errors may be generated for each case, as attempts may be made to load a shared library from multiple paths, and failure to load one symbol does not immediately abort the load.\n\nIn the official BindBC bindings, the load function for each binding will return one of these values:\n1. `noLibrary` if the library file fails to load.\n2. `badLibrary` when an expected symbol fails to load.\n3. `success`, or a version number.\n\nFor newer BindBC libraries these values belong to the `bindbc.loader.sharedlib.LoadMsg` enum. For older BindBC libraries these values belong to a binding-specific enum. For example, `SDLSupport.noLibrary` or `SDLSupport.badLibrary` for BindBC-SDL.\n\nThe function `bindbc.loader.sharedlib.errors()` returns an array of `ErrorInfo` structs that have two properties:\n\n* `error`: For a library load failure, this is the name of the library. Otherwise, it is the string `\"Missing Symbol\"`.\n* `message`: In the case of a library load failure, this contains a system-specific error message. Otherwise, it contains the name of the symbol that failed to load.\n\nHere is an example of what error handling might look like when loading the SDL library with BindBC-SDL:\n```d\nimport bindbc.sdl;\n\n/*\nImport the sharedlib module for error handling. Assigning an alias ensures that the\nfunction names do not conflict with other public APIs. This isn't strictly necessary,\nbut the API names are common enough that they could appear in other packages.\n*/\nimport loader = bindbc.loader.sharedlib;\n\nbool loadLib(){\n\tLoadMsg ret = loadSDL();\n\tif(ret != sdlSupport){\n\t\t//Log the error info\n\t\tforeach(info; loader.errors){\n\t\t\t/*\n\t\t\tA hypothetical logging function. Note that `info.error` and\n\t\t\t`info.message` are null-terminated `const(char)*`, not `string`.\n\t\t\t*/\n\t\t\tlogError(info.error, info.message);\n\t\t}\n\t\t\n\t\t//Optionally construct a user-friendly error message for the user\n\t\tstring msg;\n\t\tif(ret == SDLSupport.noLibrary){\n\t\t\tmsg = \"This application requires the SDL library.\";\n\t\t}else{\n\t\t\tSDL_version version;\n\t\t\tSDL_GetVersion(\u0026version);\n\t\t\tmsg = \"Your SDL version is too low: \"~\n\t\t\t\titoa(version.major)~\".\"~\n\t\t\t\titoa(version.minor)~\".\"~\n\t\t\t\titoa(version.patch)~\n\t\t\t\t\". Please upgrade to 2.0.16+.\";\n\t\t}\n\t\t//A hypothetical message box function\n\t\tshowMessageBox(msg);\n\t\treturn false;\n\t}\n\treturn true;\n}\n```\n\n`errorCount()` returns the number of errors that have been generated. This might prove useful as a shortcut when loading multiple libraries:\n\n```d\nloadSDL();\nloadOpenGL();\nif(loader.errorCount \u003e 0){\n\t//Log the errors\n}\n```\n\n`resetErrors()` is available to enable alternate approaches to error handling. This clears the `ErrorInfo` array and resets the error count to 0.\n\nSometimes, failure to load one library may not be a reason to abort the program. Perhaps an alternative library can be used, or the functionality enabled by that library can be disabled. For such scenarios, it can be convenient to keep the error count specific to each library:\n\n```d\nif(loadSDL() != sdlSupport){\n\t//Log errors here\n\t\n\t//Start with a clean slate\n\tloader.resetErrors();\n\t//And then attempt to load GLFW instead\n\tif(loadGLFW() != glfwSupport){\n\t\t//Log errors and abort\n\t}\n}\n```\n\n## Configurations\nBindBC-Loader is not configured to compile with BetterC compatibility by default. Users of packages dependent on BindBC-Loader should not configure BindBC-Loader directly. Those packages have their own configuration options that will select the appropriate loader configuration.\n\nImplementers of bindings using BindBC-Loader can make use of two configurations:\n* `nobc`, which does not enable BetterC, and is the default.\n* `yesbc` enables BetterC.\n\nBinding implementers should typically provide four configuration options. Two for static bindings (BetterC and non-BetterC), and two for dynamic bindings using the `nobc` and `yesbc` configurations of BindBC-Loader:\n\n|     ┌      |  DRuntime  |   BetterC   |\n|-------------|------------|-------------|\n| **Dynamic** | `dynamic`  | `dynamicBC` |\n| **Static**  | `static`   | `staticBC`  |\n\nAnyone using multiple BindBC packages with dynamic bindings must ensure that they are all configured to either use BetterC compatibility, or not. Configuring one BindBC package to use the BetterC configuration and another to use the non-BetterC configuration will cause conflicting versions of BindBC-Loader to be compiled, resulting in compiler or linker errors.\n\n## Default Windows search path\nSometimes, it is desirable to place shared libraries in a subdirectory of the application. This is particularly common on Windows. Normally, any DLLs in a subdirectory can be loaded by prepending the subdirectory to the DLL name and passing that name to the appropriate load function (e.g. `loadSDL(\"dlls\\\\SDL2.dll\")`). This is fine if the DLL has no dependency on any other DLLs, or if its dependencies are somewhere in the default DLL search path. If, however, its dependencies are also in the same subdirectory, then the DLL will fail to load\u0026emdash;the system loader will be looking for the dependencies in the default DLL search path.\n\nAs a remedy, BindBC-Loader exposes the `setCustomLoaderSearchPath` function on Windows\u0026endash;since other systems don't need to programmatically modify the shared library search path. To use it, call it prior to loading any DLLs and provide as the sole argument the path where the DLLs reside. Once this function is called, then the BindBC library's load function(s) may be called with no arguments as long as the DLL names have not been changed from the default.\n\nAn example with BindBC-SDL:\n\n```d\nimport bindbc.sdl;\nimport bindbc.loader\n\n//Assume the DLLs are stored in the \"dlls\" subdirectory\nversion(Windows) setCustomLoaderSearchPath(\"dlls\");\n\nif(loadSDL() \u003c sdlSupport){ /*handle the error*/ }\nif(loadSDL_Image() \u003c sdlImageSupport){ /*handle the error*/ }\n\n//Give SDL_image a chance to load libpng and libjpeg\nauto flags = IMG_INIT_PNG | IMG_INIT_JPEG;\nif(IMG_Init(flags) != flags){ /*handle the error*/ }\n\n//Now reset to the default loader search path\nversion(Windows) setCustomLoaderSearchPath(null);\n```\n\nIf the DLL name has been changed to something the loader does not recognise (e.g. `\"MySDL.dll\"`) then it will still need to be passed to the load function. (e.g. `loadSDL(\"MySDL.dll\")`)\n\nPlease note that it is up to the programmer to ensure the path is valid. Generally, using a relative path like `\"dlls\"` or `\".\\\\dlls\"` is unreliable, as the program may be started in a directory that is different from the application directory. It is up to the programmer to ensure that the path is valid. The loader makes no attempt to fetch the current working directory or validate the path.\n\nFor details about how this function affects the system DLL search path, see the documentation of [the Win32 API function `SetDllDirectoryW`](https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setdlldirectoryw).","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FBindBC%2Fbindbc-loader","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FBindBC%2Fbindbc-loader","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FBindBC%2Fbindbc-loader/lists"}