{"id":31455340,"url":"https://github.com/lsxprime/libloader","last_synced_at":"2025-10-01T09:55:24.809Z","repository":{"id":261649631,"uuid":"884951433","full_name":"LSXPrime/LibLoader","owner":"LSXPrime","description":"Cross-platform native library loader for .NET, simplifying the process of loading and interacting with native libraries (DLLs, SOs, dylibs) in your C# applications.  It supports dependency management, flexible loading options (local files, embedded resources, remote URLs), and provides a clean, fluent API for configuration and function calling.","archived":false,"fork":false,"pushed_at":"2024-11-07T17:27:22.000Z","size":96,"stargazers_count":15,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-08-24T17:37:13.406Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/LSXPrime.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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":"2024-11-07T17:18:45.000Z","updated_at":"2025-04-27T09:33:24.000Z","dependencies_parsed_at":"2024-11-07T18:07:39.900Z","dependency_job_id":null,"html_url":"https://github.com/LSXPrime/LibLoader","commit_stats":null,"previous_names":["lsxprime/libloader"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/LSXPrime/LibLoader","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LSXPrime%2FLibLoader","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LSXPrime%2FLibLoader/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LSXPrime%2FLibLoader/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LSXPrime%2FLibLoader/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LSXPrime","download_url":"https://codeload.github.com/LSXPrime/LibLoader/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LSXPrime%2FLibLoader/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":277824443,"owners_count":25883471,"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","status":"online","status_checked_at":"2025-10-01T02:00:09.286Z","response_time":88,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2025-10-01T09:55:23.626Z","updated_at":"2025-10-01T09:55:24.802Z","avatar_url":"https://github.com/LSXPrime.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"﻿# LibLoader: Cross-Platform Native Library Loader\n\nLibLoader is a powerful and versatile library designed to simplify the process of loading and interacting with native libraries (DLLs, SOs, dylibs, etc.) in C# applications. It provides a fluent API, cross-platform compatibility, dependency management, and various loading options, making it easier to integrate native code into your .NET projects.\n\n## Features\n\n* **Cross-Platform Compatibility:**  Leverages .NET's `NativeLibrary` for loading, supporting Windows, Linux, macOS, Android, and iOS.\n* **Dependency Management:** Automatically loads dependencies before the main library, handling versioning to ensure compatibility.\n* **Flexible Loading:** Load libraries from local files, embedded resources, or remote URLs with progress reporting and cancellation support.\n* **Progress Reporting:** Track download and loading progress using `IProgress\u003cfloat\u003e`.\n* **Customizable Logging:** Control how and where log messages are written using a `LogDelegate`.\n* **Simplified Function Calling:** Invoke native functions with type safety and automatic marshaling using the intuitive `Call` method.\n* **Data Structure Marshaling:** Supports basic types, strings, structs (including nested structs and arrays of structs), and more.\n* **Delegate Caching:** Optimizes performance by caching delegate types, reducing overhead on repeated calls.\n* **Error Handling:** Provides clear and specific exceptions for various error conditions, such as missing libraries or functions.\n* **Fluent API:**  Configure library loading using a clean and readable builder pattern, making configuration easy and maintainable.\n* **Singleton Instance:** Easily access the LibLoader instance via `LibLoader.Instance` for a streamlined workflow.\n* **Search Paths:**  Specify additional search paths to locate native libraries, simplifying dependency management.\n* **Conditional Loading:** Load a library only if a condition is met, allowing for loading libraries based on runtime conditions.\n* **Implicit Loading:** Optionally enable implicit loading to avoid loading libraries on startup. Libraries will be loaded on the first call to a native function.\n\n## Installation\n\nInstall LibLoader using the NuGet Package Manager or the .NET CLI:\n\n```\nInstall-Package LibLoader\n```\n\n## Usage\n\n### Basic Example: Loading a Local Library\n\n```csharp\nusing LibLoader;\nusing System.Runtime.InteropServices; // For StructLayout\n\n// Define a struct matching the native library's data structure\n[StructLayout(LayoutKind.Sequential)]\npublic struct MyData\n{\n    public int Value;\n    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string Message; \n}\n\npublic async Task Example()\n{\n    var loader = LibLoader.Instance\n        .ForPlatform(Platform.Windows, Bitness.X64) // Or your target platform and bitness\n        .WithLibrary()\n            .WithName(\"MyNativeLibrary\", usePlatformSpecificName:true)  // Library name (e.g., libMyNativeLibrary.so, MyNativeLibrary.dll)\n            .FromCustomPath(\"./MyNativeLibrary.dll\") // Path to the library file\n            .WithNativeFunction()\n                .Named(\"my_native_function\")\n                .WithReturnType\u003cint\u003e()\n                .WithParameter\u003cstring\u003e(\"input\")\n                .WithParameter\u003cMyData\u003e(\"data\")\n            .Add()\n        .Add()\n        .Build();\n\n    await loader.LoadAsync();\n\n    var myData = new MyData { Value = 42, Message = \"Some data\" };\n    var result = loader.Call\u003cint\u003e(\"MyNativeLibrary\", \"my_native_function\", \"Hello from C#\", myData);\n\n    Console.WriteLine($\"Result from native function: {result}\");\n\n    loader.Unload(); // Unload the library when finished\n}\n```\n\n\n\n### Advanced Scenarios\n\n#### Loading from Embedded Resources\n\n```csharp\n// ... within your LibLoader configuration ...\n.WithLibrary()\n    .WithName(\"MyEmbeddedLibrary\")\n    .FromCustomPath(\"embedded:MyNamespace.MyEmbeddedLibrary.dll\") // Path to the embedded resource.  MyNamespace.MyEmbeddedLibrary.dll should exist as an Embedded Resource in your project\n    // ... Add your native functions\n.Add();\n```\n\n\n#### Loading from Remote URL with Progress and Cancellation\n\n```csharp\nusing System.Threading;\n\n// ...\n\nvar cts = new CancellationTokenSource();\nvar progress = new Progress\u003cfloat\u003e(p =\u003e Console.WriteLine($\"Download progress: {p * 100:F2}%\"));\n\nvar loader = LibLoader.Instance\n   .WithProgress(progress)\n   .WithCancellationToken(cts.Token) // Pass the cancellation token\n   .ForPlatform(Platform.Windows, Bitness.X64)\n    .WithLibrary()\n        .WithName(\"MyRemoteLibrary\")\n        .FromRemoteUrl(\"https://example.com/MyRemoteLibrary.zip\", \"MyRemoteLibrary.dll\")  // URL and filename (if inside an archive)\n        // ... native functions\n        .Add()\n.Build();\n\n\ntry\n{\n    await loader.LoadAsync();\n    // ... call native functions ...\n}\ncatch (OperationCanceledException)\n{\n    Console.WriteLine(\"Library loading cancelled.\");\n}\nfinally\n{\n    loader.Unload();\n    cts.Dispose(); // Dispose of cancellation token source\n}\n```\n\n\n#### Specifying Dependencies (with versioning)\n\n```csharp\n// ...\n.WithDependency()  // Define the dependencies themselves\n    .WithName(\"DependencyA\")\n    .WithVersion(\"1.2.3\")\n    .FromCustomPath(\"./path/to/DependencyA.dll\") // Or a remote URL, etc.\n    .Add()\n.WithDependency()\n    .WithName(\"DependencyB\")\n    .FromRemoteUrl(\"https://example.com/DependencyB.so\")\n    .Add();\n.WithLibrary()\n    .WithName(\"MyLibrary\")\n    .WithDependencies((\"DependencyA\", \"1.2.3\"), (\"DependencyB\", null)) // Dependency name and optional version\n    // ... native functions\n    .Add()\n```\n\n#### Conditional Loading (Platform-Specific Code)\n\n```csharp\n.WithLibrary()\n    .WithName(\"MyOptionalLibrary\")\n    .WithCondition(() =\u003e RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) // Load only on Windows\n    // ... Windows-specific native functions ...\n    .Add()\n.WithLibrary()\n    .WithName(\"MyLinuxLibrary\")\n    .WithCondition(() =\u003e RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) // Load only on Linux\n    // ... Linux-specific native functions ...\n    .Add();\n```\n\n#### Custom Data Structures (Nested Structs and Arrays)\n\n```csharp\n[StructLayout(LayoutKind.Sequential)]\npublic struct InnerData\n{\n    public int Id;\n    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] public string Name;\n}\n\n[StructLayout(LayoutKind.Sequential)]\npublic struct MyData\n{\n    public int Value;\n    public InnerData Inner;\n    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] public int[] ArrayData;\n}\n\n\n// ... within the WithLibrary() builder\n.WithNativeFunction()\n    .Named(\"process_complex_data\")\n    .WithReturnType\u003cbool\u003e()\n    .WithParameter\u003cMyData\u003e(\"data\")\n    .Add()\n    // ... other native functions ...\n.Add();\n\n// ... After loading the library\nvar data = new MyData\n{\n    Value = 123,\n    Inner = new InnerData { Id = 456, Name = \"Nested\" },\n    ArrayData = new int[] { 1, 2, 3, 4, 5 }\n};\n\nvar result = loader.Call\u003cbool\u003e(\"MyLibrary\", \"process_complex_data\", data);\nConsole.WriteLine($\"Result: {result}\");\n\n```\n\n\n#### Implicit Loading (Automatic Loading on First Call)\n\n\n```csharp\n// Enable implicit loading to avoid explicitly calling LoadAsync()\nvar loader = LibLoader.Instance.WithImplicitLoading();\n// ... the rest of your LibLoader configuration (platforms, libraries, functions)\n\n//  The libraries are loaded automatically when a native function is called:\n\nvar result = loader.Call\u003cint\u003e(\"MyNativeLibrary\", \"my_function\", 10); \n// ...\n```\n\n#### Search Paths (For Dependencies or Non-Standard Locations)\n\n```csharp\n// Add search paths for native libraries\nvar searchPaths = new List\u003cstring\u003e();\nif (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))\n{\n    searchPaths.Add(@\"C:\\Path\\To\\My\\Libraries\");\n}\nelse if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))\n{\n    searchPaths.Add(\"/usr/local/lib\");\n}\n\n\nvar loader = LibLoader.Instance.WithSearchPaths(searchPaths);\n\n// ... rest of the LibLoader configuration\n```\n\n## API Documentation\n\nFull API documentation is available in the code comments and through IntelliSense within your IDE. Here's a brief overview:\n\n* **`LibLoader.Instance`:**  The singleton instance of the `LibLoader` class.\n* **`ForPlatform(Platform platform, Bitness bitness)`:**  Specifies the target platform and bitness (x86, x64, Arm, Arm64).\n* **`WithLibrary()`:** Starts a builder for defining a native library.\n* **`WithName(string libraryName)`:** Sets the name of the native library (without extension).\n* **`FromCustomPath(string path)`:** Loads the library from a specific file path.\n* **`FromRemoteUrl(string url, string? filename)`:** Downloads and loads the library from a remote URL.  `filename` is optional and specifies the filename within a zip archive.\n* **`WithDependencies(params (string name, string version)[] dependencies)`:**  Specifies dependencies for a library.\n* **`WithCondition(Func\u003cbool\u003e condition)`:** Loads the library only if the condition is true.\n* **`WithNativeFunction()`:** Starts a builder for defining a native function.\n* **`Named(string nativeName)`:** Sets the name of the native function.\n* **`WithCallingName(string callingName)`:**  Specifies the C# name for the function (optional, defaults to the native name).\n* **`WithReturnType\u003cT\u003e()` / `WithReturnType(Type returnType)`:** Sets the return type of the function.\n* **`WithParameter\u003cT\u003e(string name)`:** Adds a parameter to the function signature.\n* **`Add()`:** Adds the defined library or function to the loader.\n* **`Build()`:** Finalizes the configuration and returns the `LibLoader` instance.\n* **`LoadAsync()`:** Asynchronously loads the configured libraries. (Not necessary with implicit loading.)\n* **`Call\u003cT\u003e(string libraryName, string functionName, params object[] arguments)`:** Calls a native function with the specified name and arguments, returning a value of type T.  Overloads exist for `void` return types and to specify the return type using a `Type` object.\n* **`Unload()`:** Unloads all loaded libraries.\n\n\n## Diagram/Architecture\n\n```\n+---------------------+     +---------------------+     +---------------------+\n|    Application     | ====\u003e |    LibLoader      | ====\u003e |  Native Library  |\n+---------------------+     +---------------------+     +---------------------+\n                         (1) Configure               (2) Load \u0026 Call\n                                                      Functions\n```\n\n\n1. **Configure:** The application configures `LibLoader` with information about the native libraries to load (name, location, dependencies, functions).\n2. **Load \u0026 Call Functions:** `LibLoader` loads the specified native libraries and provides a way for the application to call functions within those libraries.  It handles dependency resolution, platform-specific loading, and data marshaling.\n\n\n## Error Handling\n\nLibLoader throws the following exceptions:\n\n* **`MissingLibraryException`:** Thrown when a required native library cannot be found.\n* **`MissingFunctionException`:** Thrown when a native function cannot be found within a loaded library.\n* **`LibraryLoadException`:** Thrown when an error occurs while loading a native library (e.g., invalid format, dependencies not met).\n* **`NativeFunctionCallException`:**  Thrown when an error occurs during a native function call (e.g., incorrect arguments, access violation).\n* `UnsupportedPlatformException`: Thrown when the current platform is not supported.\n* `UnsupportedArchitectureException`: Thrown when the current process architecture is not supported.\n\n## Contributing\n\nContributions are welcome!  Please follow these guidelines:\n\n* Fork the repository.\n* Create a new branch for your feature or bug fix.\n* Write clear and concise code with comments.\n* Submit a pull request.\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE.md) file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flsxprime%2Flibloader","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flsxprime%2Flibloader","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flsxprime%2Flibloader/lists"}