Mike
Mike

Reputation: 872

How can I make mono accept a PE32 DLL on Linux

I'm trying to build a native win32 app on Linux host using mcs mono compiler.

I have a library (CoolLib.dll) that has the following line

[global::System.Runtime.InteropServices.DllImport("MyLib.dll", EntryPoint="...")]

It's compiled using mcs and thus has the following format

$ file CoolLib.dll
PE32+ executable (DLL) (console) x86-64 Mono/.Net assembly, for MS Windows

Now, MyLib.dll is also mine and I compiled on the same host with mingw-g++.

$ file MyLib.dll
MyLib.dll: PE32+ executable (DLL) (console) x86-64, for MS Windows

I then compile my hello world executable that references CoolLib.dll...

mcs /reference:CoolLib.dll /out:main.exe /target:x64 main.cs
MONO_LOG_LEVEL=debug mono main.exe

...but it blows up with System.DllNotFoundException.

Though what I don't understand is why it complains about MyLib.dll not being an ELF

Mono: DllImport error loading library '/bindings_test/MyLib.dll': '/bindings_test/MyLib.dll: invalid ELF header'.

after all, it's supposed to be a win32 library. Why does mono expect it to be an ELF?

Upvotes: 0

Views: 655

Answers (2)

Lex Li
Lex Li

Reputation: 63203

Copied from the comments.

A few facts you need to keep in mind are,

  • Linux/macOS native executable is in ELF format (.so and others)
  • Windows native executable is in PE32 format (.dll and .exe)
  • .NET assemblies (managed) are in PE32 format (.dll and .exe)

Microsoft decided to reuse the same file extensions and file format for managed bits, so many people like you won't easily notice the big changes until moving to another operating system.

So to answer your question, if you have some C/C++ dependencies to wrap over on Linux, then they must be recompiled in ELF format using the native C/C++ compiler. Then your .NET Core/Mono apps can use PInvoke to consume them. You cannot use those native dependencies in PE32 format, because Linux won't recognize what's that.

Upvotes: 1

Brecht Sanders
Brecht Sanders

Reputation: 7287

The library generated with mcs is for target Intel 80386 while the one built with mingw-g++ is for target x86-64.

You can't mix platforms. Build everything for either 32-bit or 64-bit Windows.

For example use a 32-bit version by using a 32-bit version of MinGW-w64 or use the -m32 flag if you have a MinGW-w64 version that supports both targets.

Upvotes: 0

Related Questions