Question

I need to build DLL lib from C++ code which rely on some global static variables. Static variables of user defined classes initialized just fine while variables with primitive types (int) does not. Even more, attempt to change value of such variables lead to memory errors. What am I doing wrong?

I was able to replicate this error in a few lines example, here is my code:

mylib.hpp

#include <string>

class AAA
{
public:
    static int             & get_static_int() { return static_int_; }
private:
    static int               static_int_;
};

mylib.cpp

#include "mylib.hpp"
#include <iostream>
int               AAA::static_int_          = 42;
class BBB
{
public:
    BBB() { std::cout << "BBB constructor!!!" << std::endl; };
};
static BBB b;

mylib.def:

LIBRARY mylib
EXPORTS
   ?static_int_@AAA@@0HA

main.cpp

#include <mylib.hpp>
#include <iostream>
int main()
{
    std::cout << "get_static_int():" << AAA::get_static_int() << std::endl;
    AAA::get_static_int() = 10;  // Exception!
}

build.bat

cl /c mylib.cpp /I. /Fomylib.obj /MD /EHsc
link /MACHINE:X64 /dll mylib.obj /DEF:mylib.def /out:mylib.dll msvcrt.lib kernel32.lib oleaut32.lib
cl main.cpp mylib.lib /I. /EHsc /MD

output:

>main
BBB constructor!!!
get_static_int():403973631
<windows complain>

I am aware of similar question: Loading DLL not initializing static C++ classes and adding "-entry:_DllMainCRTStartup" to link options does not fix this problem.

I am also aware of proper way to initialize singletons in C++ but for this projects i need to port rather large Linux project and modifying/refactoring it will not be practical.

Thanks!

Was it helpful?

Solution

Using a def file isn't the best way of doing this - you should save yourself the pain by using dllexport.

If you must use def files because it has been dictated, change your def file to

LIBRARY mylib
EXPORTS
   ?get_static_int@AAA@@SAAAHXZ

As you have discovered, the function is inlined so you need to uninline it. You could use /Ob0 on the cl line but I've never found that to work. It still gets inlined and you will still get the exception. mylib.hpp should be

class AAA
{
public:
static int             & get_static_int();
private:
static int               static_int_;
};

Add the following to mylib.cpp

int& AAA::get_static_int()
{
return static_int_;
}

If you do it this way, then it should run without throwing the exception.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top