views:

421

answers:

3

Hello,

I am creating a C++ Win32 dll with some global data. There is a std::map defined globally and there are exported functions in the dll that write data into the map (after acquiring a write lock, ofcourse).

My problem is, when I call the write function from inside the dll DllMain, it works without any problems. But when I load the dll from another program and call the function that writes data into the global map, it gives me this error:

WindowsError: exception: access violation reading 0x00000008

Is there something that can be done about this? The same function when called from DllMain has access to the global data in the dll, but when called from a different process, it doesn't have access to the global data. Please advice.

I am using the TDM-MinGW gcc 4.4.0 Compiler.

EDIT: Ok, I've figured out what the problem is, and thanks for the help guys, but the problem was not with a constructor issue or inability to have maps in global space, but an issue in the boost::python that I'm using. I had tested it, but since I was calling the dll from within python or maybe something, the urllib2 module wasn't getting loaded into the dll. Now I have to see how to fix it.

+1  A: 

Looks like the constructor of std::map did not run yet when your code was called. Lifetime of global non-PODs in a Win32 DLL is pretty tricky, and I'm not certain as to how MinGW specifically handles it. But it may be that the way you're compiling the DLL, you've set your own function (DllMain?) as an entry point, and thus overrode the CRT initialization routine that calls constructors.

Pavel Minaev
I read somewhere that all global objects inside a dll get initialized before DllMain(DLL_PROCESS_ATTACH) is called. And their destructors are called after DllMain(DLL_PROCESS_DETACH) is called. So I assumed it would work and wrote too much code assuming this. But if that isn't working, would it be safe to create a global pointer and create and destroy the map inside DllMain?
Sahasranaman MS
I am fairly confident that the constructor of the std::map is getting called because I am inserting data into the map in DllMain, when the Dll is getting loaded, but once it is loaded, if I call the function from another process, it doesn't work.
Sahasranaman MS
What do you mean by "call function from another process"? A DLL is always loaded into the process in which it is used.
Pavel Minaev
This is what I meant: When the function is called by the DllMain, which is part of the Dll, the function is able to access the map. But when the function is called by the process into which the Dll is loaded, the function isn't able to access the map.
Sahasranaman MS
A: 

You have to use shared memory, because the different processes have separate address spaces. I think you won't get std::map running. I would recommend using MapViewOfFile, CreateFileMapping, OpenFileMapping, ... and plain old data. Ask Google / MSDN.

ur
The data that I am mentioning is required/used only by the dll that I am creating, and the application that uses the dll doesn't need access to the data. Is there any other way to let the function access the data?
Sahasranaman MS
Perhaps you can define one of the processes to be the owner of the data? And: Are the keys and values serialzable? Then you could use some means of inter process communication. This will be okay if the other processes don't make too much use of the map.
ur
+1  A: 

A read error at such a low memory address generally means that you are trying to access a NULL pointer somewhere. Can you show your actual code?

Remy Lebeau - TeamB