2016-09-06 80 views
-1

我一直在努力使用Visual Studio 2015编译大量的代码文件,这些代码文件原本是用于Linux,使用g ++。 具体而言,我需要一个用于其他程序的.dll。不幸的是,我遇到了一些问题。使用dll编译链接,但导致段错误

做了一些研究后,我尝试在头文件中添加__declspec(dllexport)。这有助于解决一些编译错误,但不适用于静态成员函数和变量。然后,我创建了一个.def文件,该文件摆脱了编译中的其余错误,但在运行一些同时编译的测试(并使用相同的编译器)时,由于段错误,其中很多失败。 这些相同的测试成功,如果我将它构建为.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++的新手),我宁愿不必对源代码本身进行非常多的编辑,但似乎应该做更多的事情与

任何帮助了解这里发生了什么将不胜感激。

+0

[This](http:// stackoverflow。com/a/19374253/3344612)回答应该给你一些提示 – teivaz

+0

我不是def文件的专家,但是我在上次链接中使用了__declspec dllimport/dllexport语义的时候已经取得了巨大的成功。我很好奇,你有什么问题与__declspec(dllexport)? –

+0

我建议,不要运行静态成员。用dllexport函数代替。用函数封装静态成员。 – neohope

回答

0

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

您必须使用dllexport和dllimport作为一对。 dllexport在共享库(dll)和dllimport中将它们定义在应用程序中使用它们的位置。您通常会有一个宏,根据它使用的位置来计算__declspec(dllexport)或__declspec(dllimport)。例如。

#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文件。

+0

我误解了如何使用这些宏。当我正确使用__declspec时,测试成功。谢谢大家。 – ejwilson