Trying to use Microsoft compiled DLLs on Linux

2023-10-03

This semester my studies at TalTech include a course on C++. Nothing special, I have used that language before, I have KDevelop all setup and know my way around configuring extra settings, if required. That is what I thought, at least.

In order to pass this course one is required to submit some Coursework projects, which use data generated by a custom DLL which the instructor provides. So I started thinking, how can I use a DLL, which is typically Windows specific, on Linux. The internet was not particularly optimistic about converting the DLL to a shared object file which could have been used without much trouble. So instead I looked into using wine. With wine I would be able to run a Windows build of my code on Linux, and they even provide tools like winegcc that make building software from Windows easier.

To start my experiments I dusted off my largely unused Windows installation and followed the setup guide that came with the instructions for using the DLL. Installing Visual Studio (which is available in the Windows store, but clicking install does not do anything), trying to create the project with a specific template, noticing that that template is not there, installing the C++ desktop development collection for an additional 10GB (at this point I had to switch from my VM to an external disk because of space constraints), noticing that the template is still not there and using a different one, following the steps to configure using the accompanying .LIB file and building release and debug versions and finally spending hours to realise that the DLL is 32-bit and my program therefore needs to target that as well.

Once I had a working project I copied it over to linux and tried building it with winegcc. After a number of errors I arrived at it just not using the DLL/LIB and instead complaining about the functions defined there being undefined. This lead me to post my first ever question on Stack Overflow, were it was quickly pointed out that the result of GCC and Microsoft's compiler are simply incompatible. I feel like I had heard about this at some point but it definitely was not active knowledge. I wonder what process would help catching such oversights before pouring hours of work into some idea.

Hope was not lost though, as the same commenter also pointed me to Clang. Clang tries to be compatible with all kinds of things, including the microsoft C compiler. The folks behind Clang also maintain a tool called clang-cl, which wraps a bunch of options for the regular clang and is supposed to provide results that are compatible with Microsoft's msvc. Of course, this too didn't work right out of the box and required a bunch of custom include paths for compiler and linker which pointed to directories stlen from Windows and I also had to specify that I wanted to use the lld linker instead of linker.exe. But then this actually worked. A single command compiles and links my code and gives me an exe file.

Realising this took me some time though. To run the exe I would use wine, but wine would mostly just print debug output, including complaiing about failed IO activity. So I went about fixing those. Aside from my knowledge on compiling C++, one thing has really benefited from all of this, my wine installation. A ot of clean up, permission overhaul and so on went into slowly reducing the amount of debug lines. And yet, my program output was nowhere to be seen. My genius had not included any output statements.

With all those hurdles overcome the last step was to integrate this into KDevelop, which was surprisingly easy. Only one issue, all my debugging output related to why the program crashes comes from wine and is just a number of memory addresses. I recommend writing code that works on first try should you use such a setup. (Or figure out how to make debugging nicer).

As for creating this setup, I have compiled a set of instructions on how to get there.

Trying to use Microsoft compiled DLLs on Linux © 2023 by Andreas Hurka is licensed under CC BY 4.0