{"id":26145764,"url":"https://github.com/rdotnet/dynamic-interop-dll","last_synced_at":"2025-04-14T03:09:36.262Z","repository":{"id":23429925,"uuid":"26792926","full_name":"rdotnet/dynamic-interop-dll","owner":"rdotnet","description":"Facilities to load native DLLs from .NET. More flexible and hide platform specifics.","archived":false,"fork":false,"pushed_at":"2024-02-05T14:38:42.000Z","size":112,"stargazers_count":37,"open_issues_count":4,"forks_count":22,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-14T03:09:31.397Z","etag":null,"topics":["dotnet","dotnet-core","native-libraries","pinvoke"],"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/rdotnet.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"License.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":"2014-11-18T05:09:03.000Z","updated_at":"2024-11-15T13:37:29.000Z","dependencies_parsed_at":"2024-06-18T13:53:07.298Z","dependency_job_id":null,"html_url":"https://github.com/rdotnet/dynamic-interop-dll","commit_stats":{"total_commits":78,"total_committers":4,"mean_commits":19.5,"dds":0.2692307692307693,"last_synced_commit":"04a6665981e84ac9dfdcd92f04444e21734c9772"},"previous_names":["jmp75/dynamic-interop-dll"],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rdotnet%2Fdynamic-interop-dll","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rdotnet%2Fdynamic-interop-dll/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rdotnet%2Fdynamic-interop-dll/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rdotnet%2Fdynamic-interop-dll/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rdotnet","download_url":"https://codeload.github.com/rdotnet/dynamic-interop-dll/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248813795,"owners_count":21165634,"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":["dotnet","dotnet-core","native-libraries","pinvoke"],"created_at":"2025-03-11T04:55:11.566Z","updated_at":"2025-04-14T03:09:36.242Z","avatar_url":"https://github.com/rdotnet.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n[![Linux master Build Status](https://travis-ci.org/jmp75/dynamic-interop-dll.svg?branch=master \"Linux master Build Status\")](https://travis-ci.org/jmp75/dynamic-interop-dll/builds)\n\n[![Windows master Build Status](https://ci.appveyor.com/api/projects/status/otm2yg0os9rpn5j1?branch/master?svg=true \"Windows master Build Status\")](https://ci.appveyor.com/project/jmp75/dynamic-interop-dll/branch/master) \n\n[![DOI](https://zenodo.org/badge/26792926.svg)](https://zenodo.org/badge/latestdoi/26792926)\n\n[![Nuget Version](https://buildstats.info/nuget/DynamicInterop)](https://www.nuget.org/packages/DynamicInterop/)\n\ndynamic-interop-dll\n===================\n\nFacilities to load native DLLs from .NET, on Unix, Windows or MacOS.\n\n# Purpose\n\nThis library is designed to facilitate load dynamic link libraries (called shared libraries on unix-type of platforms) from `.NET`, and the interop between the two worlds. The loading mechanism adapts to the operating system it is running on. It is an offshoot from the [R.NET](http://rdotnet.codeplex.com) project (source code now hosted [on github](https://github.com/rdotnet/rdotnet)). \n\n\n```c\nMY_C_API_MARKER void Play(void* simulation, const char* variableIdentifier, double* values, TimeSeriesGeometry* geom);\n```\n\n```c#\n    [DllImport(\"libswift.dll\", EntryPoint = \"Play\", CallingConvention = CallingConvention.Cdecl)]\n    private static extern void Play(\n        [In] IntPtr modelSimulation,\n        [In] string variableIdentifier,\n        [In] [MarshalAs(UnmanagedType.LPArray)] double[] values,\n        ref MarshaledTimeSeriesGeometry geom);\n```\n\n```c#\n    public void Play(IModelSimulation modelSimulation, string variableIdentifier, MinimalTimeSeries series)\n    {\n        var handle = modelSimulation.DangerousGetHandle();\n        var geom = new MarshaledTimeSeriesGeometry(series);\n        MsDotnetNativeApi.Play(handle, variableIdentifier, series.Data, ref geom);\n    }\n```\n\n```c#\n    private delegate void Play_csdelegate(IntPtr simulation, string variableIdentifier, IntPtr values, IntPtr geom);\n    // and somewhere in a class a field is set:\n    NativeLib = new UnmanagedDll(someNativeLibFilename);\n\n    void Play_cs(IModelSimulation simulation, string variableIdentifier, double[] values, ref MarshaledTimeSeriesGeometry geom)\n    {\n        IntPtr values_doublep, geom_struct;\n        // here glue code here to create native arrays/structs\n        NativeLib.GetFunction\u003cPlay_csdelegate\u003e(\"Play\")(CheckedDangerousGetHandle(simulation, \"simulation\"), variableIdentifier, values_doublep, geom_struct);\n        // here copy args back to managed; clean up transient native resources.\n    }\n```\n\n# License\n\nThis library is covered as of version 0.7.3 by the [MIT license](https://github.com/rdotnet/dynamic-interop-dll/blob/3055f27f46d1b794572bcd944eaebbd4f960b9a6/License.txt).\n\n# Installation\n\nYou can install this library in your project(s) [as a NuGet package](https://www.nuget.org/packages/DynamicInterop)\n\nFor some Linux flavours you may need to also compile a [workaround for a \"invalid caller\" error](#libdl-workaround). This has been observed on some CentOS flavours. Debian, Ubuntu appear fine.\n\n# Usage\n\nAn extract from the unit tests:\n\n```c#\nprivate void TestLoadKernel32()\n{\n    using (var dll = new UnmanagedDll(\"kernel32.dll\"))\n    {\n        var beep = dll.GetFunction\u003cBeep\u003e();\n        Assert.NotNull(beep);\n        //beep(400, 1000);\n        var areFileApisAnsi = dll.GetFunction\u003cAreFileApisANSI\u003e();\n        Assert.DoesNotThrow(() =\u003e areFileApisAnsi());\n    }\n}\n\nprivate delegate bool Beep(uint dwFreq, uint dwDuration);\nprivate delegate bool AreFileApisANSI();\n```\n\n# Building\n\nThe command line for building and testing are largely platform neutral. you will need `dotnet` to build and optionally `cmake` to compile and run some of the unit tests, on Linux.\n\nFollow the instructions for your platform to install `dotnet` if need be via [Download .NET](https://www.microsoft.com/net/download). Which version of nuget you have may matter too (beware older versions coming from some deb repos), see [https://docs.microsoft.com/en-us/nuget/guides/install-nuget](https://docs.microsoft.com/en-us/nuget/guides/install-nuget) to retrieve the latest nuget.exe.\n\n```bash\ndotnet restore\n# ignore the restore fail for DynamicInterop.Tests/test_native_library/test_native_library.vcxproj if you get any\ndotnet build --configuration Debug --no-restore\n```\n\n## testing\n\nif on Linux, you need to compile the test native library:\n\n```bash\ncd DynamicInterop.Tests\ncd test_native_library\ncmake -H. -Bbuild\ncmake --build build -- -j3\n# cmake --build build \ncd ../..\n```\n\nOn Windows:\n\n```bat\nset DynamicInteropTestLibPath=C:\\src\\dynamic-interop-dll\\x64\\Debug\n```\n\nOn Linux:\n\n```bash\nexport DynamicInteropTestLibPath='/home/path/to/dynamic-interop-dll/DynamicInterop.Tests/test_native_library/build'\n```\n\nthen you can run unit tests:\n\n```bash\ndotnet test DynamicInterop.Tests/DynamicInterop.Tests.csproj\n```\n\nIf, in the output of the unit test, you see an 'invalid caller' message from the dlerror function, read on the next section. This issue is known to happen on some Linux distros.\n\n## libdl workaround for Linux\n\nOn Linux, DynamicInterop calls the dlopen function in \"libdl\" via P/Invoke to try to load the shared native library, On at least one instance of one Linux flavour (CentOS), it fails and 'dlerror' returns the message 'invalid caller'. See https://rdotnet.codeplex.com/workitem/73 for detailed information. Why this is an \"invalid caller\" could not be determined. While the exact cause if this failure is unclear, a thin wrapper library around libdl.so works around this issue.\n\nYou build and install this workaround with the following commands:\n\n```bash\nDYNINTEROP_BIN_DIR=~/my/path/to/DynamicInteropBinaries\ncd libdlwrap\nmake\nless sample.config # skim the comments, for information\ncp sample.config $DYNINTEROP_BIN_DIR/DynamicInterop.dll.config\ncp libdlwrap.so  $DYNINTEROP_BIN_DIR/\n```\n\n## Building the nuget package\n\n*This section is primarily a reminder to the package author.*\n\n```bash\ndotnet pack DynamicInterop/DynamicInterop.csproj --configuration Release --no-build --no-restore --output nupkgs\n# Or for initial testing/debugging\ndotnet pack DynamicInterop/DynamicInterop.csproj --configuration Debug --no-build --no-restore --output nupkgs\n```\n\nIf you have an additional nuget package repository for tests:\n\n```cmd\ncp .\\DynamicInterop\\nupkgs\\DynamicInterop.0.9.0-beta.nupkg c:\\local\\nuget\n```\n\n# Related work\n\nI did notice that [a related library](https://github.com/Boyko-Karadzhov/Dynamic-Libraries) with some overlapping features has been released just a week ago (as of when I wrote this)... While I want to explore possibilities to merge these libraries, I have pressing needs to release present library release as a stand-alone package.\n\n# Acknowledgements\n\n* Kosei designed and implemented the original multi-platform library loading\n* evolvedmicrobe contributed the first implementation that did not require OS-specific conditional compilation.\n* Daniel Collins found the workaround necessary for the library loading to work some Linux platforms, via Mono.\n* jmp75 refactored, tested, merged contributions and separated from the original R.NET implementation.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frdotnet%2Fdynamic-interop-dll","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frdotnet%2Fdynamic-interop-dll","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frdotnet%2Fdynamic-interop-dll/lists"}