0

I'm crating a DLL in C++ which handles different classes: in particular I have a main class which have a lot of member objects of the other the classes. For exmaple I have my class "A" which has a member of class "B": Class A header

#include "BClass.h"
class __declspec(dllexport) A
{
B* objectB = nullptr;
public:
A();
initClassB();
}

Class A cpp:

A::A() { // Class A constructor. In these statements B is still nullptr}
A::initCLassB() { objectB = new B()  }

Class B header:

class __declspec(dllexport) B
{
int x; 
bool y; 
char* z; 
public:
B() { // class B constructor}
}

When I import my DLL in my target project, it compiles with no error, and until here everything's ok. My main is something like:

#include "AClass.h"
int main()
{
A a; 
return 0;
}

Notice that I don't invoke initClassB() in my main and this cause the error "Unable To Read Memory". If I explore the debugger I see that the error is related to all A::objectB members. Why is this happening? Can't the shared library handle a nullptr member object?

I'm quite new in compiling DLL and this error looks a bit weird to me

Evethir
  • 31
  • 3
  • do you get the eror with the code you posted? Comments that suggest that code was left out is always suspicious – 463035818_is_not_an_ai Nov 21 '19 at 16:31
  • 1
    What is your DLL trying to do with the nullptr member object? If its trying to act on the object, or access any of its members, then it will fail. – Adrian Mole Nov 21 '19 at 16:32
  • Why do you not initialize B? Are you trying to read a null object and expect to get meaningful results? It's not clear what you expect to happen, or exactly what line you're on when you see the error you mention, and so on. You need to be really detailed about the exact situation that produces your error if you want the best help. Otherwise you're just asking people to guess. – Chris Uzdavinis Nov 21 '19 at 16:38
  • unfortunately I got no error code from the build. I noticed this error because my main program crashes during execution, therefore I opened the debugger and noticed the error message on the member of A::objectB, which it is still a null pointer and it is normal that its member are not allocated. but why is the crash happening ? A::objectB isn't invoked/used anywhere and keep it as a nullptr is something that I want.. It seems that this is not legal with DLLs and I'd like to understand why – Evethir Nov 21 '19 at 16:38
  • @Evethir It is perfectly legal to have `nullptr` values for pointer members in a DLL. The problem is not with that, at least not conceptually. Maybe something does try to use that member. Or maybe this is just a symptom of UB elsewhere. According to your explanation, no `B` instance should be created during your program, so there isn't even a `B` object for the program to try to access the members of (your debugger will of course say "unable to read memory" if you inspect `objectB`, but that's entirely expected and normal - it doesn't tell you more about the crash). – Max Langhof Nov 21 '19 at 16:44
  • thanks everybody for the support. I'm doing some deeper tests. I'll keep you updated. I'm using the DLL in the CryEngine, maybe there are some engine logics that I'm ignoring. We'll see – Evethir Nov 22 '19 at 09:52

1 Answers1

2

DLLs on windows need to export their symbols when building the dll. Client code that uses the library needs to import it.

In your header for class B:

class __declspec(dllexport) B

This is what you want when building the library, but in code that uses it, you want it to be dllimport instead. Usually people use macros to toggle this, with it defaulting to import, and only exporting if a special commandline macro is set.

See this Macro for dllexport/dllimport switch

Chris Uzdavinis
  • 6,022
  • 9
  • 16
  • Ehi Chris, thanks for your answer. I didn't specify it, but in my client code the macro is ```dllimport``` instead of ```dllexport```, so I don't think that the problem is related to that – Evethir Nov 21 '19 at 16:47