Created
November 4, 2025 03:41
-
-
Save fiddyschmitt/ad1d89804074c78dc518c4068878b780 to your computer and use it in GitHub Desktop.
Use a native windows dll in Linux
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Say you have a native Windows library called libfoo.dll that you'd like to use in Linux. The following instructions describe how to wrap it in a .NET application and use Wine to run it. | |
| 1) Generate bindings | |
| Using Visual Studio: | |
| Use BindingGenerator (below) to generate C# bindings to the DLL. | |
| The output folder will contain libfoo.cs | |
| 2) Write a wrapper program | |
| Write a program which uses libfoo.cs | |
| If required, instantiate objects using the Foo.cs example below | |
| Compile the program as follows: | |
| Right-click the Project | |
| Publish -> Folder | |
| Show all settings | |
| Configuration: Release | |
| Target framework: net8.0 | |
| Deployment mode: Self-contained | |
| Target Runtime: win-x64 | |
| Produce single file: Tick | |
| Once published, copy the required DLLs into the output folder | |
| 3) Run the program on Linux | |
| apt-get update | |
| apt install wine -y | |
| wine app.exe |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using CppSharp; | |
| using CppSharp.AST; | |
| using CppSharp.Generators; | |
| using CppSharp.Parser; | |
| namespace BindingGenerator | |
| { | |
| public class BindingGenerator : ILibrary | |
| { | |
| public static void Main(string[] args) | |
| { | |
| ConsoleDriver.Run(new BindingGenerator()); | |
| } | |
| // Setup the driver options and module information. | |
| public void Setup(Driver driver) | |
| { | |
| var options = driver.Options; | |
| options.GeneratorKind = GeneratorKind.CSharp; | |
| var parserOptions = driver.ParserOptions; | |
| parserOptions.LanguageVersion = LanguageVersion.C99; | |
| parserOptions.MicrosoftMode = true; | |
| // Define the module containing your C++ library details | |
| var module = options.AddModule("libfoo"); | |
| module.IncludeDirs.Add(@"D:\libfoo\headers"); | |
| module.Headers.Add("interface.h"); | |
| module.LibraryDirs.Add(@"D:\libfoo"); | |
| module.Libraries.Add("libfoo.dll"); | |
| options.OutputDir = Path.Combine(Directory.GetCurrentDirectory(), "GeneratedBindings"); | |
| // Optional: Configure specific calling conventions if necessary | |
| // options.CallingConvention = CallingConvention.Cdecl; | |
| } | |
| public void SetupPasses(Driver driver) | |
| { | |
| // Passes can be added here to customize the AST (Abstract Syntax Tree) | |
| // before generation (e.g., to rename specific functions or ignore some declarations). | |
| } | |
| public void Preprocess(Driver driver, ASTContext ctx) | |
| { | |
| // Preprocessing step: filter out unwanted declarations. | |
| // For example, you can ignore specific functions or classes here. | |
| } | |
| public void Postprocess(Driver driver, ASTContext ctx) | |
| { | |
| // Postprocessing step: make final adjustments to the generated bindings. | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using System.Collections.Generic; | |
| using System.Linq; | |
| using System.Runtime.InteropServices; | |
| using System.Text; | |
| using System.Threading.Tasks; | |
| using libfoo; | |
| using static DemoFoo.Utilities.Utils; | |
| namespace libfoo | |
| { | |
| public unsafe partial class FooInputs | |
| { | |
| public FooInputs() | |
| { | |
| __Instance = Marshal.AllocHGlobal(sizeof(__Internal)); | |
| MemoryManagement.RtlZeroMemory(__Instance, sizeof(__Internal)); | |
| } | |
| } | |
| public unsafe partial class FooOutputs | |
| { | |
| public FooOutputs() | |
| { | |
| __Instance = Marshal.AllocHGlobal(sizeof(__Internal)); | |
| MemoryManagement.RtlZeroMemory(__Instance, sizeof(__Internal)); | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using System.Collections.Generic; | |
| using System.Linq; | |
| using System.Runtime.InteropServices; | |
| using System.Text; | |
| using System.Threading.Tasks; | |
| namespace DemoFoo.Utilities | |
| { | |
| public static class Utils | |
| { | |
| public static class MemoryManagement | |
| { | |
| [DllImport("kernel32.dll")] | |
| public static extern void RtlZeroMemory(IntPtr dst, int length); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment