与DLL链接会编译,但会导致段错误 [英] Linking with a dll compiles, but causes a segfault

查看:145
本文介绍了与DLL链接会编译,但会导致段错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在与Visual Studio 2015一起使用g ++编译大量最初为Linux使用而编写的代码文件。
具体来说,我需要一个.dll与其他程序一起使用。不幸的是,我遇到了许多问题。

I've been working on compiling with Visual Studio 2015 a large number of code files written originally for use on linux, using g++. Specifically, I need a .dll for use with another program. Unfortunately, I have run into a number of problems.

经过一些研究,我尝试将__declspec(dllexport)添加到头文件中。这有助于解决一些编译错误,但不适用于静态成员函数和变量。然后,我制作了一个.def文件,该文件消除了编译中剩余的错误,但是在运行同时(并使用相同的编译器)编译的一些测试时,许多测试由于段错误而失败。
如果我将其构建为.lib,或者将测试直接链接到各种目标文件,则这些测试也会成功,但是对于最终程序,我需要一个.dll(使用g ++的原始版本会生成.so) 。
我找不到其他人遇到类似的问题。

After doing some research, I tried adding __declspec(dllexport) to the header files. This helped with some of the compilation errors, but didn't work for the static member functions and variables. I then made a .def file, which got rid of the remaining errors in compilation, but upon running some of the tests compiled at the same time (and with the same compiler), many of them failed due to segfaults. These same tests succeed if I build it as a .lib, or if I link the tests directly to various object files, but for the final program I need a .dll (The original build using g++ builds a .so). I have been unable to find anyone else with a problem similar to this.

这是我发现的一些代码的简化版本。与将导致段错误的行之一相关:

Here is a simplified version of some of the code which I have found to be relevant to one of the lines which will cause a segfault:

在库中,标题为:

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

和cpp文件:

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

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

Anything in the test file which references this variable will cause a segfault with a .dll. Specifically, if I have the line

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

然后,如果链接到.dll,它将进行段错误处理,但是如果链接到.lib,则将进行隔离输出

then if linked to a .dll it will segfault, but if linked to a .lib, it will output

FIRST_CLASS

由于这是一个更多的项目,可以编译其他人创建的大量代码(不是我所理解的全部,对于c ++来说还很陌生),所以我宁愿不必对源代码进行太多编辑本身,但似乎应该与

As this is a project more to compile a large amount of code created by others (not all of which I understand, being rather new to c++), I would rather not have to do very much editing of the source code itself, but it seems like it should be more to do with

有更多的关系,

推荐答案

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

The static data in the dll is in a different address space so you can't directly reference it (the call has to be mapped thru an import table). When you link a static library everything is in the address space of the executable so you can.

必须将dllexport和dllimport结合使用。在共享库(dll)中定义它们的dllexport和在应用程序中使用它们的dllimport。通常,您会使用一个宏,该宏的取值取决于__declspec(dllexport)或__declspec(dllimport)的使用情况。例如

You must use dllexport and dllimport as a pair. dllexport where you define them in the shared library (dll) and dllimport where you use them in the application. You'll typically have a macro that evaluates to either __declspec(dllexport) or __declspec(dllimport) depending on where it's used. E.g.

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

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

And use it where you define the class:

class DLLExportImport FirstClass
{ ... };

在适当的位置定义符号 _DLL 各自的项目。创建新的dll项目时,Visual Studio会预定义 _DLL

Defining the symbol _DLL as appropriate in the respective projects. Visual Studio predefines _DLL when you create a new dll project.

大多数情况下都不需要.def文件这些日子。

There is no need for .def files in most cases these days.

这篇关于与DLL链接会编译,但会导致段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆