0

I am curious about being able to use the most primitive ever DLL-library compiled in Windows, in Linux-compiled C++ code. Let's assume that library in question is not the monstrous proprietary something from Windows core;

…just one with phony API like (here are both header and implementation):

// MathFuncsDll.h

namespace MathFuncs
{
    class MyMathFuncs
    {
    public:
        // Returns a + b
        static __declspec(dllexport) double Add(double a, double b);

        // Returns a - b
        static __declspec(dllexport) double Subtract(double a, double b);
    };
}


// MathFuncsDll.cpp

#include "MathFuncsDll.h"

using namespace std;

namespace MathFuncs
{
    double MyMathFuncs::Add(double a, double b)
    {
        return a + b;
    }

    double MyMathFuncs::Subtract(double a, double b)
    {
        return a - b;
    }
}

This library would have no dependencies other than <iostream>, would it?

Linux-compiled .cpp would contain the following:

// MyExecRefsDll.cpp
// compile with: /EHsc /link MathFuncsDll.lib

#include <iostream>

#include "MathFuncsDll.h"

using namespace std;

int main()
{
    double a = 7.4;
    int b = 99;

    cout << "a + b = " <<
        MathFuncs::MyMathFuncs::Add(a, b) << endl;
    cout << "a - b = " <<
        MathFuncs::MyMathFuncs::Subtract(a, b) << endl;

    return 0;
}

Samples were taken from amazing MSDN tutorial.

So, to make my question clear: what stops linux compiler and linking tools from using dependenceless .dll library MathDuncsDll just like another .so? Maybe, another call syntax? Or maybe the whole linking process is different? (I'd like to hear specifics, not just vague "these OS'es are fundamentionally different" and "it is impossible to use something from one platform on another") How much effort will these differences require to be overcome (I assume we're not using Wine)?

Thank you very much in advance!

fyodorananiev
  • 2,683
  • 4
  • 18
  • 24
  • 1
    You might want to Google "NdisWrapper", a Linux tool which can load actual Windows drivers. That shows you can definitely call Windows code from Linux, but not easily. – MSalters Oct 21 '12 at 13:04

3 Answers3

5

This should answer your question: https://stackoverflow.com/a/1908981/856199.

Windows uses the COFF format, Linux uses ELF. Those are not compatible. Furthermore, Windows and Linux have different ABIs (see http://en.wikipedia.org/wiki/Application_binary_interface). That means the code, even if it were to load and execute, would result in garbage since communication with the rest of the system would be scrambled. For example a function would expect its data and code to reside in different addresses and in a different order. The result of trying to execute that code would be virtually random.

Of course a Linux compiler could use the Windows ABI and produce COFF files. And actually, it can, and does; it is called a "cross compiler". I'm using one of those to build Windows libraries and *.exe files under Linux. But using the same binary file both as a Linux .so and a Windows .dll is not possible due to COFF vs ELF and ABI differences.

Community
  • 1
  • 1
Nikos C.
  • 47,168
  • 8
  • 58
  • 90
  • Great! I'd like to know which system calls my simple examples do. I don't understand this low-level layer of interaction between OS and programs. Can you supply some links for reading? – fyodorananiev Oct 20 '12 at 20:53
  • 2
    @furikuretsu There aren't any system calls in that code, but that doesn't matter. The problems lie elsewhere. For example how the compiled machine instructions are stored in the binary file. Windows can't parse that file, and thus can't even load the code. Even if it could, there's the problem of finding the names inside the C++ library. `cout` for example. In Linux this might be named differently than Windows. See http://en.wikipedia.org/wiki/Name_mangling for an explanation. And then, even if you get past the name mangling, you still have to deal with the ABI differences. – Nikos C. Oct 20 '12 at 21:01
  • 2
    (continued) For example, the size of your MyMathFuncs class will be different between Linux and Windows, and the addresses of its members and the layout of its vtable will be different too. A call to MyMathFuncs::Add() will therefore result in trying to execute random data as if it were code. – Nikos C. Oct 20 '12 at 21:05
2

Incompatible Application Binary Interface is what restricts programs built with one toolchain to not work at the binary level with those compiled with other toolchains.

For example, on Windows in C++, the exception propagation follows the Set Jump/ Long Jump model while in Linux its Dwarf 2. If you have ever used MinGW as your toolchain on Windows, the TDM-GCC MinGW distribution allows you to choose between the two.

If you want to use any cross-platform project, you would need to build it using a toolchain with which you have been building your rest of the programs, otherwise they cannot work in tandem.

The linked SO answer contains much more details about this.

Community
  • 1
  • 1
vvnraman
  • 1,222
  • 12
  • 21
  • Thank you for great answer! ABI-related question contained remark by bta which was the closest to what I needed to hear. – fyodorananiev Oct 21 '12 at 19:53
1

In addition of other answers, there are different semantics on linking in Windows and in Linux, read Levine's book on linkers and loaders for more.

Basile Starynkevitch
  • 1
  • 16
  • 251
  • 479