0

我很好奇能够在 Linux 编译的 C++ 代码中使用在 Windows 中编译的最原始的 DLL 库。让我们假设有问题的库不是来自 Windows 核心的可怕的专有东西;

…只有一个带有假API的(这里是标题和实现):

// 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;
    }
}

这个库除了 <iostream> 之外没有其他依赖项,不是吗?

Linux 编译的 .cpp 将包含以下内容:

// 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;
}

示例取自令人惊叹的 MSDN 教程。

所以,为了明确我的问题:是什么阻止了 linux 编译器和链接工具MathDuncsDll像另一个 .so 一样使用无依赖的 .dll 库?也许,另一种调用语法?或者整个链接过程可能不同?(我想听听细节,而不仅仅是模糊的“这些操作系统根本不同”和“不可能在另一个平台上使用某些东西”)这些差异需要付出多少努力才能克服(我假设我们'不使用Wine)?

非常感谢您!

4

3 回答 3

5

这应该回答您的问题:https ://stackoverflow.com/a/1908981/856199 。

Windows 使用 COFF 格式,Linux 使用 ELF。这些不兼容。此外,Windows 和 Linux 有不同的 ABI(参见http://en.wikipedia.org/wiki/Application_binary_interface)。这意味着代码,即使要加载和执行,也会导致垃圾,因为与系统其余部分的通信会被打乱。例如,一个函数会期望它的数据和代码以不同的顺序驻留在不同的地址中。尝试执行该代码的结果几乎是随机的。

当然,Linux 编译器可以使用 Windows ABI 并生成 COFF 文件。实际上,它可以而且确实如此;它被称为“交叉编译器”。我正在使用其中之一在 Linux 下构建 Windows 库和 *.exe 文件。但是由于 COFF 与 ELF 和 ABI 的差异,无法将相同的二进制文件同时用作 Linux .so 和 Windows .dll。

于 2012-10-20T20:42:39.477 回答
2

不兼容的应用程序二进制接口限制了使用一个工具链构建的程序不能在二进制级别上与使用其他工具链编译的程序一起工作。

例如,在 C++ 中的 Windows 上,异常传播遵循 Set Jump/Long Jump 模型,而在 Linux 中则遵循 Dwarf 2。如果您曾经在 Windows 上使用 MinGW 作为工具链,TDM-GCC MinGW发行版允许您在二。

如果您想使用任何跨平台项目,则需要使用您一直用来构建其余程序的工具链来构建它,否则它们无法协同工作。

链接的 SO 答案包含有关此的更多详细信息。

于 2012-10-20T20:51:43.110 回答
1

除了其他答案之外,Windows 和 Linux 中的链接还有不同的语义,请阅读Levine 关于链接器和加载器的书了解更多信息。

于 2012-10-21T06:45:29.400 回答