MFC-related crash when calling constructors - c++

I'm currently writing an application using MFC and CLR in visual studio, and my program is crashing whenever I call the constructor of a class I've written (the class is to control a camera over USB).
I've got a base class CameraBase:
class CameraBase
{
public:
virtual bool getFrame(cv::Mat& outImage) { return true; };
};
and a derived class LumeneraCamera (for the specific camera):
class LumeneraCamera : public CameraBase
{
public:
DLL_API LumeneraCamera();
DLL_API bool connect(int cameraNum);
DLL_API bool disconnect();
DLL_API bool getFrame(cv::Mat& outImage);
private:
//Bunch of misc variables
};
These classes are compiled into a DLL and accessed from another program:
int main()
{
cout << "Initing camera" << endl;
camera = new LumeneraCamera();
//More operations
}
When I run the program, it prints Initing camera and then fails because of an assertion in dllinit.cpp (line 133: VERIFY(AfxInitExtensionModule(controlDLL, hInstance));). It crashes before executing anything in the constructor. I'm not really sure what the problem is but it seems tied to MFC, so I'm currently looking into untangling my project from MFC entirely. Any suggestions or fixes are appreciated!

According to MSDN, if your DLL is dynamically linked against the MFC DLLs, each function exported from this DLL which call into MFC must have the AFX_MANAGE_STATE macro added at the very beginning of the function:
AFX_MANAGE_STATE(AfxGetStaticModuleState());

I eventually solved it by disabling MFC - a library I was using suggested MFC but as far as I can tell works fine without it.

Related

Overriding C++ entry point to be a STATIC method of a class

Preface and the problem
I'm currently studying C++ programming language and game programming.
At the moment, I'm working on a simple game engine just to practice 'consistency' and architecture of the API, and due to this reason the idea of mimicing C# 'Program' class appeared.
C# Entry point:
class Program
{
static void Main(string[] args)
{
// Do stuff.
}
}
C++ analogue required:
class Program
{
public:
static void Main()
{
// Do stuff. 'args' analogue can be ignored, if necessary.
}
};
Is it possible to somehow, using linker options, redefine entry point to be a static class method?
Related experience and my theories on this topic
The main reason, why I think, this should be possible is described in the following piece of code (that was successfully compiled using mingw-w64).
#include <iostream>
class Main
{
public:
static void Foo() { std::cout << "Main::Foo\n"; }
};
void localFoo() { std::cout << "localFoo\n"; }
void callFunc(void(*funcToCall)())
{
funcToCall();
}
int main()
{
callFunc(localFoo);
callFunc(Main::Foo); // Proves that Main::Foo has the same interface as localFoo.
return 0;
}
(Refers to Win32 API) I abstracted Win32 API into classes and used window procedure as a static member of class. It was absolutely correct to Win32 WNDCLASS and I could even use static members of my class inside this procedure.
Conslusion I made: static fields and methods technically have no differences between global variables and functions, and, since that, they can replace some code, that dates back to C (default entry point, for example).
Notes
Both MinGW and MSVC (Visual Studio or cmd) solutions are acceptable.
The author of the post is extremely grateful for any information provided :3
Is it possible to somehow, using linker options, redefine entry point to be a static class method?
No. Not if you want to use the C++ runtime library, at any rate. main (or WinMain) is called by the runtime library once it has completed initialising itself, and that call is hard-coded in the runtime library itself.
The MSVC linker lets you specify an alternative entry point with the /ENTRY switch (see here), but if you do that you will bypass the runtime library initialisation code and that will break things.

C++ nullptr member objects cause "Unable To Read Memory" in DLL Shared Library

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
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

How can I allow singleton constructor re-entry/pass-over in VS2017?

I've been porting some c++ app from Visual Studio 2013 to Visual Studio 2017. Aside from the plethora of new warnings that I had to fix, the compilation and linking went okay.
However, when running the app, it 'stalled' when trying to re-enter the constructor of a singleton (when successive function calls form a loop back to the constructor). It seems that this behaviour was okay in VS2013, but is no longer valid in VS2017. There is no error message.
I'm aware of all the bad things related to singletons, and that there should at least not be loops. The question is not there.
Is there a way to tell the VS2017 compiler that I'd like to shoot myself in the foot, and allow the same behaviour that was there in VS2013?
I don't have access to the code that causes this behaviour because it comes from a third-party library, this is why I can't 'just fix it', unfortunately.
Here is an example which works in VS2013, but doesn't work in VS2017:
main.cpp
#include "Singleton.h";
int
main( void )
{
std::cout << "let's do this!" << std::endl;
int two = Singleton::GetReference().getTwo();
std::cout << "ok" << std::endl;
return 0;
}
Singleton.h
#pragma once
class Stuff;
class Singleton
{
public:
static Singleton& GetReference();
int getTwo() { return 2; }
private:
Singleton();
Stuff* stuff;
};
Singleton.cpp
#include "Singleton.h"
#include "Stuff.h"
Singleton&
Singleton::GetReference() {
static Singleton theInstance;
return theInstance;
}
Singleton::Singleton()
{
stuff = new Stuff();
}
Stuff.h
#pragma once
class Stuff
{
public:
Stuff();
private:
int two;
};
Stuff.cpp
#include "Stuff.h"
#include "Singleton.h"
Stuff::Stuff()
{
two = Singleton::GetReference().getTwo();
}
In the code above, when step-by-step debugging, the first time we get on the line static Singleton theInstance; will work as expected, but the second time, a F11 will go to the file thread_safe_statics.cpp, into the method extern "C" void __cdecl _Init_thread_header(int* const pOnce). A Shift+F11 will exit the method and the program will wait indefinitely at the line specified (observed when pausing the program from the debugger).
PS
This issue probably occurs in Visual Studio 2015 too, as the documentation linked from the accepted answer mentions VS2015.
/Zc:threadSafeInit-
The general "Conformance" page is MSDN: Conformance, which details which new features you can disable.
I needed the code for sizedDealloc, where my new compiler was creating a sized new operator for a library which broke older compiled expectations.
As this is a compile flag, at least some of the code would be in your control, and you should be able to unravel the beast.
The constructor Stuff::Stuff is calling a function on an incompletely constructed object.
That would create "Undefined behavior". If the value "2" is not set till the end of the constructor (for example).
Probably the Singleton needs to be split into 2, one which delivers the early static data (e.g. 2).
The second which delivers the held object Stuff. Stuff would only rely on the first, which would break the deadlock.
Alternatively, a second constructor to Stuff which told it which object to use, and was called from the Singleton::Singleton
The MSDN article to disable "Magic Statics" MSDN : disable threadsafe static initialization

How to correctly expose interfaces from a dll in the presence of VC++ 2015 whole program optimization

recently we encountered in our legacy code that is currently ported from VS2010 to VS2015 an interesting effect. Unfortunately I couldn't create a small example that shows this effect, but I'll try to describe it as accurately as I can.
We have 2 dlls (I'll call them dll A and dll B). The project for dll A defines the interface IFoo & a derived interface IFxFoo
class __declspec(novtable) IFoo {
public:
virtual int GetType() = 0;
virtual ~IFoo() {}
};
class __declspec(novtable) IFxFoo : public IFoo {
public:
virtual int GetSlot() = 0;
};
in dll B, both interfaces are used.
class CBImpl : public IFxFoo {
public:
...
void processFoo(IFoo* f) {
...
if (f->GetType() == IFXFOO) {
IFxFoo* fx = static_cast<IFxFoo>(f); //downcast
fill(fx);
}
}
void fill(IFxFoo* fx) {
m_slot = fx->GetSlot();
}
private:
int m_slot;
};
processFoo() will be called with different implementations of IFoo. Some from dll A and some from dll B.
What now happened was the following:
- if we turned on whole program optimization when compiling dll B, the call to the virtual function GetSlot() in function fill() got de-virtualized by Visual C++. This caused our program to crash.
we can fix this behavior if we either
turn of whole program optimization
turn of optimization for fill
or mark our interfaces with __declspec(dllimport) / __declspec(dllexport)
The questions that I have now are:
is our assumption correct that the de-virtualization happened because the optimizer saw only one implementation of IFxFoo in dll B and assumed that this is the only one because IFxFoo was not marked to be from a different dll?
what's the best way to create "interfaces" in header files? We used to do them like above but this seems to lead to some problems.
do other compiler (gcc / clang) exhibit similar behavior?
Thank you for your help
Tobias
Using LTO results in the compiler making drastic adjustments to any functions for which is it able to see the complete callgraph.
What you are seeing is expected and using __declspec(dllexport) or extern on the functions that need to be utilised from a separate module or explicitly declaring them as part of a DLL .def file is the expected way to resolve the problem as the compiler will no longer consider the functions to be internal-only.

Crash in program when trying to access base class vector member from a drived class instance loaded from a DLL

I'm running into a strange crash. I am trying to separate out various modules of my Application (MFC based, developed in VS2005) into DLLs. Following is the skeletal code of how I'm trying to achieve it:
In a common Header file(say base.h):
class Base {
vector<message> messages;
...
...
};
In a header file in DLL source code(say class.h):
class Derived : public Base {
private:
int hoo();
...
public:
void foo();
int goo();
...
};
extern "C" __declspec (dllexport) Derived* CreateDerived();
In class.cpp
Derived* CreateDerived()
{
return new Derived;
}
In a file in main Application code:
#include "base.h"
#include "class.h"
typedef Derived* (*DerivedCreator)();
...
...
void LoadDll()
{
//DLL Load Code...
...
...
DerivedCreator creator = reinterpret_cast<DerivedCreator>(::GetProcAddress(dllHandle, "CreateDerived"));
Derived* pDerived = creator();
pDerived->messages.push_back(message("xyz"));//Crashes here...
}
The problem is the code craches the moment I try to access the vector member of the Base class. This only happens in Release mode. It works fine in Debug mode. The error message that i get when I execute it from Visual Studio in Release mode is:
"Microsoft Visual Studio C Runtime Library has detected a fatal error in Samsung SSD Magician.exe.
Press Break to debug the program or Continue to terminate the program."
But when I execute the release binary directly and attach the debugger to it, I get an Access Violation. At this point if I check the vector in debugger, it shows 6-digit entries in it, none of them readable. I'm able to see correct values of rest of the members of Base class in the Derived pointer.
Any help would be much appreciated.
It's dangerous to pass stl containers across a DLL boundary.
The reason here is that each module (the main application and the DLL) has it's own instance of the heap. If you allocate dynamic memory in the context of DLL, then pass the pointer to the application and release that memory in the context of the application, that causes heap corruption.
That is exactly what happens in your example.
Derived* pDerived = creator();
CreateDerived is called.
Derived* CreateDerived()
{
return new Derived;
}
new Derived allocates memory in DLL heap.
pDerived->messages.push_back(message("xyz"));
Inside push_back, an additional memory is allocated for Base::messages, and that allocation is done on the application heap. Crash!
A conclusion is that you need to rethink the DLL interface in order to perform all operation on the vector only inside the DLL.