views:

140

answers:

2

Hi,

I have a static class member

class bar {...}

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

Now I call a function which accesses this member within a shared library, I get a memory error whereas when I access the function through the main program, it works fine. I've tested this under a number of circumstances.

I initialize the variable in the main application but I don't intialize it again in the shared library (it seemed unnecessary).

I'm using GCC and QT in Ubuntu.

What going and how can I fix it?

+1  A: 

IIRC the exe and shared library will get their own copies of static member variables like that, and that as such you will need to initialise it separately in each case.

Since its a pointer, one way may be to initialise it in your main program as normal and then pass the pointer to the dll when you load it so that the dll's version can be set to point to the same place as the exe's one.

EDIT: Ok, I did some tests (Windows, VC9), and it appears that globals, and static variables (be it function, class, whatever) are per-module (i.e. every exe and dll will gets it's own copy, even if the variable came from a common source, like say a static library).

I'm going to test to see if the dllimport/export on the class makes them use a common copy.

EDIT2:

Ok using __declspec(dllexport) in the dll and __declspec(dllimport) in the exe (use preprocessor macros to switch between them depending on what includes the header), for the static variable declaration made the static variable common to both modules. It also works for global variables, and I'll assume static function variables.

#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 however doesn't have dllexport and dllimport, however it may have some other way of achieving the same effects when creating shared libaries (be it a dll or so).

If it doesn't, then the only other solution I can think of is what I first suggested. Initialise your static pointer in the exe, then have a function in the dll to set the static var, which the exe can call passing its copy of the pointer.

Fire Lancer
I got that feeling. Anyone have documentation on this?
Joe Soul-bringer
Hmm, keep in mind that I'm using gcc/Linux
Joe Soul-bringer
A: 

By using "section" attributes can be placed on specific sections apart from data and bss. Only in windows these sections can be shared across executable by using the "shared" attribute. In other platforms this feature is not supported. So the solution would be as mentioned in the previous answer.

Andy