在c ++中调用来自共享库的列表的静态指针

时间:2009-12-05 03:29:21

标签: c++ linux qt gcc libraries

我有一个静态类成员

class bar {...}

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

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

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

我在Ubuntu中使用GCC和QT。

进展如何以及如何解决?

2 个答案:

答案 0 :(得分:1)

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

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

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

我将测试以查看类中的dllimport / export是否使它们使用公共副本。

EDIT2:

确实在exe中使用__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中有一个函数来设置静态var,exe可以调用它来传递它的指针副本。

答案 1 :(得分:0)

通过使用“section”属性可以放在除data和bss之外的特定部分。仅在Windows中,可以使用“共享”属性跨可执行文件共享这些部分。在其他平台中,不支持此功能。所以解决方案就像上一个答案中提到的那样。