链接与DLL编译,但会导致段错误

时间:2016-09-06 22:15:25

标签: c++ dll visual-studio-2015

我一直在使用g ++编译Visual Studio 2015中最初用于在linux上编写的大量代码文件。 具体来说,我需要一个.dll用于另一个程序。不幸的是,我遇到了很多问题。

在做了一些研究后,我尝试将__declspec(dllexport)添加到头文件中。这有助于解决一些编译错误,但对静态成员函数和变量没有任何作用。然后我创建了一个.def文件,它解决了编译中剩余的错误,但是在运行一些同时编译的测试(并使用相同的编译器)时,其中许多因segfaults而失败。 如果我将它构建为.lib,或者将测试直接链接到各种目标文件,这些相同的测试会成功,但对于最终的程序,我需要一个.dll(使用g ++的原始构建构建一个.so)。 我一直无法找到与此类似的问题的其他人。

以下是一些代码的简化版本,我发现这些代码与导致段错误的其中一行相关:

在库中,标题:

class FirstClass
{
public:
  static const char *FIRST_CLASS_NAME;
}

和cpp文件:

const char *FirstClass::FIRST_CLASS_NAME = "FIRST_CLASS";

测试文件中引用此变量的任何内容都将导致带有.dll的段错误。具体来说,如果我有行

std::cout << FirstClass::FIRST_CLASS_NAME << std::endl;

然后如果链接到.dll就会出现段错误,但如果链接到.lib,则会输出

FIRST_CLASS

由于这是一个更多的项目来编译由他人创建的大量代码(并非我所理解的所有代码,对于c ++来说都是新手),我宁愿不必对源代码本身进行非常多的编辑,但似乎应该更多地与

有关

任何帮助理解这里发生的事情都会非常感激。

1 个答案:

答案 0 :(得分:0)

dll中的静态数据位于不同的地址空间中,因此您无法直接引用它(该调用必须通过导入表进行映射)。链接静态库时,所有内容都在可执行文件的地址空间中,因此您可以。

您必须使用dllexport和dllimport作为一对。 dllexport,您可以在共享库(dll)和dllimport中定义它们,您可以在应用程序中使用它们。您通常会有一个宏,其值为__declspec(dllexport)或__declspec(dllimport),具体取决于它的使用位置。 E.g。

#ifdef _DLL     // inside the DLL
  #define DLLExportImport __declspec(dllexport)
#else          // outside the DLL
   #define DLLExportImport __declspec(dllimport)
#endif

在你定义类的地方使用它:

class DLLExportImport FirstClass
{ ... };

在相应项目中根据需要定义符号_DLL。在创建新的dll项目时,Visual Studio会预定义_DLL

现在大多数情况下都不需要.def文件。