我一直在使用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 ++来说都是新手),我宁愿不必对源代码本身进行非常多的编辑,但似乎应该更多地与
有关任何帮助理解这里发生的事情都会非常感激。
答案 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文件。