从 C++ 中的共享库调用指向列表的静态指针

Posted

技术标签:

【中文标题】从 C++ 中的共享库调用指向列表的静态指针【英文标题】:Calling static pointer to a list from a shared library in c++ 【发布时间】:2009-12-05 03:29:21 【问题描述】:

我有一个静态类成员

class bar ...

class foo 
    public:
        static QHash<qint64,bar>* barRepHash;

现在我在共享库中调用一个访问该成员的函数,我得到一个内存错误,而当我通过主程序访问该函数时,它工作正常。我已经在多种情况下对此进行了测试。

我在主应用程序中初始化了变量,但我没有在共享库中再次初始化它(这似乎没有必要)。

我在 Ubuntu 中使用 GCC 和 QT。

发生了什么,我该如何解决?

【问题讨论】:

这里没有足够的细节来回答这个问题。问题可能是 barRepHash 未设置为有效的内存位置。有崩溃的 GDB 回溯吗? 这可能是因为 barRepHash 在被共享库访问时没有正确初始化。但如果没有进一步的信息,就无法确切说明为什么会发生这种情况。 【参考方案1】:

IIRC exe 和共享库将获得它们自己的静态成员变量副本,因此您需要在每种情况下单独初始化它。

由于它是一个指针,一种方法可能是在您的主程序中正常初始化它,然后在加载它时将指针传递给 dll,以便可以将 dll 的版本设置为指向与 exe 相同的位置一个。

编辑: 好的,我做了一些测试(Windows,VC9),看起来全局变量和静态变量(无论是函数、类还是其他)都是每个模块的(即每个 exe 和 dll 都会得到它自己的副本,即使变量来自一个共同的来源,比如一个静态库)。

我要测试一下,看看类上的 dllimport/export 是否让他们使用了一个通用的副本。

EDIT2:

好的,在 dll 中使用 __declspec(dllexport) 并在 exe 中使用 __declspec(dllimport)(使用预处理器宏在它们之间切换,具体取决于包含头文件的内容),因为静态变量声明使静态变量对两个模块都通用。它也适用于全局变量,我将假设静态函数变量。

#pragma once

//defined when compiling test.dll
#ifdef TEST_EXPORTS
#define DLL __declspec(dllexport)
#else
#define DLL __declspec(dllimport)
#endif

//foo and bar definition in test.cpp, ie only in the dll's compile
class X

public:
    static int foo;
;
DLL extern int bar;

AFAIK GCC 但是没有 dllexport 和 dllimport,但是在创建共享库时它可能有一些其他方式来实现相同的效果(无论是 dll 左右)。

如果没有,那么我能想到的唯一其他解决方案就是我最初建议的解决方案。在exe中初始化你的静态指针,然后在dll中有一个函数来设置静态变量,exe可以调用它来传递它的指针副本。

【讨论】:

我有那种感觉。有人有这方面的文档吗?【参考方案2】:

通过使用“节”属性可以放置在数据和 bss 之外的特定节上。只有在 Windows 中,这些部分才能通过使用“共享”属性跨可执行文件共享。在其他平台中,不支持此功能。因此解决方案将如上一个答案中所述。

【讨论】:

以上是关于从 C++ 中的共享库调用指向列表的静态指针的主要内容,如果未能解决你的问题,请参考以下文章

Qt 共享库(动态链接库)和静态链接库的创建及调用

从 Python 调用 C++ 64 位共享库

C++ 静态库中的共享全局变量

C ++释放共享库中动态分配的内存导致崩溃

C++ 静态库中的共享全局变量:Linux

从 C++ 调用共享库