No call to CWinThread:ExitInstance - visual-studio-2010

In my dialog based application, in CWinApp::InitInstance I create class that has framed window v1:
creating modHolder
CWinThread* pThread= AfxBeginThread(RUNTIME_CLASS(modHolder));
declaring modHolder
class modHolder : public CWinThread
{
DECLARE_DYNCREATE(modHolder)
protected:
modHolder(); // protected constructor used by dynamic creation
virtual ~modHolder();
public:
CMainWindow * v1;
virtual BOOL InitInstance();
virtual int ExitInstance();
protected:
DECLARE_MESSAGE_MAP()
};
During application close I expect to get call to modHolder::ExitInstance()
Unfortunately I have no this function. What might be problem? I think, that CWinThread modHolder should terminate automatically. Am I wrong?

CWinThread::ExitInstance is called when CWinThread::Run finishes.
You have the source code!

Related

C++11 Call virtual member function

I`m trying to implement something like this using C++11.
class Proto{
public:
virtual void fu() = 0;
};
class Impl: public Proto{
public:
void fu();
};
void Impl::fu(){
LOG_INFO("im fu");
}
class Inv{
public:
void useFu(void (Proto::*)());
};
void Inv::useFu(void (Proto::*fu)()){
//fu();
};
void main(){
Impl impl;
Inv inv;
//inv.useFu(impl.fu);
}
useFu(void (Proto::*)()) must be declared in this way because, fu() uses some specific to Proto functionality's
I have two places were things going wrong.
First is fu() call itself and second how to pass fu as parameter inv.useFu(impl.fu).
Edit after bipll answer
The suggested usage of inv.useFu() solves the second problem of my question.
inv.useFu(static_cast<void (Proto::*)(void)>(&Impl::fu));
But I still need to call fu as a pointer to member function;
The way your useFu is declared now, it should be called as
inv.useFu(static_cast<void (Proto::*)(void)>(&Impl::fu));
But I guess that's not what you wanted. It should rather be
template<class F> void useFu(F &&f) { std::invoke(std::forward<F>(f)); }
or simply
void useFu(std::function<void()> f) { std::invoke(std::move(f)); }
and called as
useFu([&]{ impl.fu(); });
(Rather than using a lambda you can bind the method to the object with std::bind in the latter call but almost nobody ever does that.)

LabVIEW: How to pass the reference of the event object as well as the indicator's reference to the callback

I am trying to figure out a way to display a variable updated by .NET while LabVIEW's callback is called by .NET.
I have a simple application called "EventGenerator" written with .NET and what it does is that upon calling Start() it automatically increments a variable called IncrementingValue. Once Stop() is called it stops to increment.
Every time the variable is updated the property is changed (eg. PropertyChanged)
I want to use a callback to display on the indicator. So I registered a callback for the variable and I want to display the updated value on the indicator.
Is there a way to pass the reference of the event object as well as the indicator's reference to the callback so that the callback can update the value ?
.NET code
namespace EventGenerator
{
public ref class GeneratorClass : System::ComponentModel::INotifyPropertyChanged
{
// Public functions
public:
GeneratorClass();
~GeneratorClass() { };
void Start();
void Stop();
void Reset();
private:
void EventThreadHandler();
// INotifyPropertyChagned
public:
void OnPropertyChanged(System::String^ info);
virtual event System::ComponentModel::PropertyChangedEventHandler^ PropertyChanged;
// Properties
public:
property int IncrementingValue
{
internal:
void set(int value)
{
m_incrementingValue = value;
OnPropertyChanged("IncrementingValue");
}
public:
int get()
{
return m_incrementingValue;
}
}
LabVIEW code
Test: Front panel
Ok button event
Stop button event
Reset button event
Callback front panel
Callback

C++/CLI unhandled exception passing 3 or more parameters to delegate

Just stumbled upon strange behavior.
I have an unmanaged class (actually wrapper around some native lib):
//.h
class Wrapper
{
private:
void(*pCallback)(int, int /*, int*/);
public:
void SetCallback(void(*callback)(int, int /*, int*/));
void InvokeCallback();
};
//.cpp
void Wrapper::SetCallback(void(*callback)(int, int /*, int*/))
{
pCallback = callback;
}
void Wrapper::InvokeCallback()
{
pCallback(0, 0 /*, 0*/); //(1)
//(3)
}
And managed class which is winforms control and uses unmanaged wrapper described above:
public ref class MineControl : public System::Windows::Forms::Control
{
private:
Wrapper *pWrapper;
delegate void CallbackDelegate(int, int /*, int*/);
public:
MineControl()
{
/* rest of initialization here */
pWrapper = new Wrapper;
auto dlg = gcnew CallbackDelegate(this, &MineControl::Method);
auto ptr = System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(dlg);
void(*callback)(int, int /*, int*/) = (void(*)(int, int /*, int*/))(ptr.ToPointer());
pWrapper->SetCallback(callback);
pWrapper->InvokeCallback();
}
void Method(int a, int b /*, int c*/)
{
//some code or even nothing at all
//(2)
}
}
This works fine.
Until I uncomment third parameter. After that I put breakpoint on (1). I can enter to MineControl::Mehod - (2). But everything fails on exiting this method. Point (3) become unreachable. I'm getting unhandled exception on exiting that method. Moreover being attached, VS still cannot handle that exception (all settings to debug unmanaged and managed code are set - this is the only case VS cannot catch exception). So Windows tries to handle it - standard App has stopped working window with two options - Debug and Close program. But I cannot debug because VS is still attached and either do not want to detach or app dies on VS detach.
I can wrap all parameters into some structure and this will work well. However can someone explain me why adding third parameter makes it impossible to get back from managed to unmanaged code?
I have no idea what is going on.
Environment: VS2013, x86 project, .net4.5
Ok, I'll post answer by myself. Solution is actually in Hans's comment.
Default calling convention is sdtcall but in my case I need cdecl calling convention.
Decorating delegate with [UnmanagedFunctionPointer(CallingConvention.Cdecl)] attribute solved my problem.
There is also а valuable note that keep delegate in a local variable is a bad idea.

A delegate to a virtual method where does it point to (base/derived)?

I recently started using C++/Cli for wrapping purposes.
Now I'm at a point where I've to know more about the internals.
Consider the following code:
Header file (ignoring .NET namespaces for this example):
public ref class BaseyClass
{
protected:
delegate void TestMethodDelegate(); // TestMethod delegate
BaseyClass(); // constructor
virtual void TestMethod(); // member: method
GCHandle _testMethodHandle; // member: method handle
};
CPP file (ignoring .NET namespaces for this example):
BaseyClass::BaseyClass()
{
_testMethodHandle
= GCHandle::Alloc(
gcnew TestMethodDelegate(this, &BaseyClass::TestMethod));
}
void TestMethod()
{
}
Eventually this class will be used as base class (for a DerivedClass) later and the method "TestMethod()" gets overridden and called from unmanaged code through the delegate pointer.
Now the question: Which method will be referenced by the delegate?
BaseyClass::TestMethod();
or
DerivedClass::TestMethod();
Personally I think the "BaseyClass::TestMethod()" will be referenced by the delegate because even when it's overridden, the delegate points to the (base-)address of BaseyClass. Hence a DerivedClass cannot override the "TestMethod" and use the delegate from BaseyClass.
I just want to be sure. Thanks for your comments and enlightment.
The delegate will be a reference to the derived class's TestMethod. Even though you're passing &BaseyClass::TestMethod, that's a virtual method, you're also passing this, which is the derived type, and both of those are taken into account when the delegate is created.
Other notes:
TestMethodDelegate doesn't need to be inside the class definition. The more standard way is to have the delegate outside of the class, just in the namespace. (Or use the existing built-in one, Action.)
You don't need to GCHandle::Alloc (I assume that's what you meant by Allow). Instead, declare _testMethodHandle as TestMethodDelegate^ (or Action^). In general, you shouldn't need to deal with GCHandle unless you're interfacing with unmanaged code, and this code is all managed.
Here's my test code:
public ref class BaseyClass
{
public:
BaseyClass() { this->_testMethodHandle = gcnew Action(this, &BaseyClass::TestMethod); }
virtual void TestMethod() { Debug::WriteLine("BaseyClass::TestMethod"); }
Action^ _testMethodHandle;
};
public ref class DerivedClass : BaseyClass
{
public:
virtual void TestMethod() override { Debug::WriteLine("DerivedClass::TestMethod"); }
};
int main(array<System::String ^> ^args)
{
BaseyClass^ base = gcnew DerivedClass();
base->_testMethodHandle();
return 0;
}
Output:
DerivedClass::TestMethod

Qt: Connecting SIGNAL to SLOT in 2 different windows

I'm going nuts trying to find the problem here. I have a main window, and a form type window made in Qt. I'm using the Visual Studio 2010 addon. For some reason, my SLOT is never called in the main window; however, the signal appears to be emitted.
Here's what I've done:
This is the form:
class ScalerValuesWindow : public QWidget
{
Q_OBJECT
private:
Ui::ScalerValuesWindow ui;
// Variables
std::vector<int> scalerValues;
public slots:
void storeScalerValues();
signals:
void ScalerValues(std::vector<int>);
public:
ScalerValuesWindow(QWidget *parent = 0);
};
void ScalerValuesWindow::storeScalerValues()
{
emit ScalerValues(scalerValues);
hide();
}
Then here's my main window connection line in my constructor:
scalerValuesWindow = new ScalerValuesWindow;
connect(scalerValuesWindow, SIGNAL(ScalerValues(std::vector<int>)), this, SLOT(RetrieveScalerValues(std::vector<int>)));
This is in my main window's class declaration:
public slots:
void RetrieveScalerValues(vector<int> scalerValues);
And this is the slot:
void RelayduinoGuiThreading::RetrieveScalerValues(vector<int> scalerVals)
{
scalerValues = scalerVals;
}
I have Q_OBJECT declared in both. I have no idea what could be causing this.
Any advice would be greatly appreciated.
You must define your slot as:
public slots:
void RetrieveScalerValues(std::vector<int> scalerValues);
^^^
(Inspect the generated moc file to see exactly what signal/slot signatures are being generated.)
Don't use using namespace std; in your headers, that's bad practice anyway (pulls in that huge namespace into all the users of that header, which is impolite).

Resources