Spawning new async request from an asio handler - c++

I'm trying to get my feet wet with ASIO and thought a good first project would be a simple web crawler: download an html page, find the links in it, download all the links.
I have tried modifying the ASIO http client example to use enable_shared_from_this instead of a raw pointer so that I can spawn new async task from within the handler of the previous task without having to worry about the resources getting deleted in the middle of my work.
The problems start when I tried to subclass my client to handle different pages in different ways. The compiler complains that the type of the shared_ptr doesn't match the type of this.
Does anybody know how this is solved? I haven't been able to figure it out by myself.

This is unrelated to Asio.
If you inherited a base class from enable_shared_from_this, but need it in the derived one, use boost::static_pointer_cast:
struct base : enable_shared_from_this<base>
{
};
struct derived : base
{
shared_ptr<derived> shared_from_derived()
{
return static_pointer_cast<derived>(shared_from_this());
}
};

Related

Adding non-cObject data (custom class) into a packet in Omnet++

I am trying to create a packet and attach a custom object. I read through the manual and tried following their suggestions but I am stuck.
According to the manual: Non-cObject data can be attached to messages by wrapping them into cObject, for example into cMsgPar which has been designed expressly for this purpose.
cMsgPar has the function: setObjectValue(), so I attempted to add the class via this code:
// b is a pointer to a custom object
auto packet = createPacket("Msg");
packet->addPar("data");
packet->par("data").setObjectValue(b);
but I get a 'no matching function for call' error for the setObject value function. I checked the function declaration, which is:
cMsgPar & setObjectValue (cOwnedObject *obj)
which brings me back to square one. Trying to convert my custom class into something acceptable by Omnet to send to other nodes in my network.
Any help would be appreciated.
The recommended way of carrying own classes (objects) via message in OMNeT++ is to add this to definition of a message. For example:
cplusplus {{
#include "MyClass.h" // assuming that MyClass is declared here
typedef MyClass *MyClassPtr;
}};
class noncobject MyClassPtr;
packet MyPacket {
int x;
MyClassPtr ptr;
}
Reference: OMNeT++ Simulation Manual - 6.6 Using C++ Types
this is how i do it as an easy solution. Omnet++ already gave alot of ways to do it.
msg->addPar("preamble");
msg->par("preamble").setLongValue(0b01010101010101);
send(msg,"phyout");
i hope it will helpout

How to make a C++ boost::signal be caught from an object which encapsulates the object which emits it?

I have a TcpDevice class which encapsulates a TCP connection, which has an onRemoteDisconnect method which gets called whenever the remote end hangs up. Then, there's a SessionManager object which creates TcpSession objects which take a TcpDevice as a communication channel and inserts them in an internal pointer container for the application to use. In case any of the managed TcpSessions should end, I would like the SessionManager instance to be notified about it and then remove the corresponding session from the container, freeing up the resources associated with it.
I found my problem to be very similar to this question:
Object delete itself from container
but since he has a thread for checking the connections state, it gets a little different from mine and the way I intended to solve it using boost::signals, so I decided to go for a new question geared towards it - I apologize if it's the wrong way to do it... I'm still getting the feel on how to properly use S.O. :)
Since I'm kind of familiar with QT signals/slots, I found boost::signals offers a similar mechanism (I'm already using boost::asio and have no QT in this project), so I decided to implement a remoteDeviceDisconnected signal to be emitted by TcpDevice's onRemoteDisconnect, and for which I would have a slot in SessionManager, which would then delete the disconnected session and device from the container.
To initially try it out I declared the signal as a public member of TcpDevice in tcpdevice.hpp:
class TcpDevice
{
(...)
public:
boost::signal <void ()> remoteDeviceDisconnected;
(...)
}
Then I emitted it from TcpDevice's onRemoteDisconnect method like this:
remoteDeviceDisconnected();
Now, is there any way to connect this signal to my SessionManager slot from inside session manager? I tried this:
unsigned int SessionManager::createSession(TcpDevice* device)
{
unsigned int session_id = session_counter++;
boost::mutex::scoped_lock lock(sessions_mutex);
sessions.push_back(new TcpSession(device, session_id));
device->remoteDeviceDisconnected.connect(boost::bind(&SessionManager::removeDeadSessionSlot, this));
return session_id;
}
It compiles fine but at link time it complains of multiple definitions of remoteDeviceDisconnected in several object code files:
tcpsession.cpp.o:(.bss+0x0): multiple definition of `remoteDeviceDisconnected'
tcpdevice.cpp.o: (.bss+0x0): first defined here
sessionmanager.cpp.o:(.bss+0x0): multiple definition of `remoteDeviceDisconnected'
tcpdevice.cpp.o: (.bss+0x0): first defined here
I found this strange, since I didn't redefine the signal anywhere, but just used it at the createSession method above.
Any tips would be greatly appreciated! Thank you!
My bad! Like we all should expect, the linker was right... there was indeed a second definition, I just couldn't spot it right away because it wasn't defined by any of my classes, but just "floating" around one of my .cpp files, like those found on boost::signals examples.
Just for the record, the initial idea worked like a charm: when a given TcpDevice gets disconnected from the remote end, it emits the remoteDeviceDisconnected signal, which is then caught by the SessionManager object which holds the TcpSession instance that points to that TcpDevice. Once notified, SessionManager's method removeDeadSessionSlot gets executed, iterating through the sessions ptr_list container and removing the one which was disconnected:
void SessionManager::removeDeadSessionSlot()
{
boost::mutex::scoped_lock lock(sessions_mutex);
TcpSession_ptr_list_it it = sessions.begin();
while (it != sessions.end()) {
if (!(*it).device->isConnected())
it = sessions.erase(it);
else
++it;
}
}
Hope that may serve as a reference to somebody!

Need help with events in COM in pure C++!

guys! Very important question:
Please, look at my project (300Kb). I can`t use MFC/ATL, pure C++ only.
I have COM library (niapi.dll), but no sources/headers available, dll only.
There is class for connecting to server (NiApi::SrvrSession), class has login event handler (NiApi::SrvrSession::OnLogin).
I used
#import "NiApi.dll"
to generate wrappers/information,
then
ISrvrSessionPtr session(L"NiApi.SrvrSession");
to create object, then trying
session->put_OnLogin();
to assign events, but there is no one put_On or such member.
niapi.tlh have _ISrvrSessionEvents struct inside, but it have no relations with SrvrSession.
I need to use events from NiApi::SrvrSession for handling connection status.
Please help or my boss kill me! (sorry for broken english, I read better than speak;)
COM events are handled via connection points. You need to write your own COM object that implements whichever event interface you are interested in. Then you need to connect it to the COM object that fires the events. First you QI the COM object for its IConnectionPointContainer, then find the corresponding connection point of the GUID of the event interface. The you call its Advise method to connect it to your event sink.
class CSrvrSessionEvents: public _ISrvrSessionEvents
{
public:
HRESULT OnLogin(long LoginResult)
{
// do something
return S_OK;
}
// implement rest of _ISrvrSessionEvents
};
ISrvrSession* pSrvrSession = ...; // get ISrvrSession from somewhere
_ISrvrSessionEvents* pSrvrSessionEvents = new CSrvrSessionEvents();
IConnectionPointContainer* pCPC = NULL;
pSrvrSession->QueryInterface(IID_IConnectionPointContainer, &pCPC);
IConnectionPoint* pCP = NULL;
pCPC->FindConnectionPoint(__uuidof(_ISrvrSessionEvents), &pCP);
DWORD dwCookie = 0;
pCP->Advise(pSrvrSessionEvents, &dwCookie);
pSrvrSession->Connect(); // I assume this fires some events
pCP->Unadvise(dwCookie);
What is really necessary, is to carefully read
codeproject_TEventHandler.
All explained here.
The put_ prefix is the default prefix for the raw interface (customizable via the raw_property_prefixes attribute). Since you are not using the raw interface, use session->OnLogin=... instead.
For event handling see ADO Events Model Example (VC++)

Outlook Add-in. How to manage Items Events

I'm doing an add-in for Outlook 2007 in C++.
I need to capture the events like create, change or delete from the Outlook Items (Contact, Appointment, Tasks and Notes) but the only information/examples I've found are for Visual Basic so I don't know how to connect the event handler.
Here is some information related: http://msdn.microsoft.com/en-us/library/bb208390(v=office.12).aspx
Any help is welcome :) Thanks
Update
Sorry for taking this long to update, I've been out of town. I have some doubts/problems that you may know how to help.
In my case, I'm taking this project that was started so I'm a bit confused about all this. I have the class OutlookAddin that derives from IDTExtensibility2. I also have this other class, called AutoSync, were I'd like to do all the methods when the event fires and so. An object of this class is initialized in OutlookAddin.cpp OnStartupComplete.
According to your post MyClass should extends from IDispEventSimpleImpl<1 /*N*/, MyClass, &__uuidof(Outlook::ItemsEvents)> but which one of them? OutlookAddin or AutoSync ?
Where I should put this code also?
CComPtr<Outlook::MAPIFolder> folder;
// get the folder you're interested in
CComPtr<Outlook::_Items> items;
hr = folder->get_Items(&items);
hr = MyItemEvents::DispEventAdvise(items, &__uuidof(Outlook::ItemsEvents));
typedef IDispEventSimpleImpl<1 /*N*/, MyClass,
&__uuidof(Outlook::ItemsEvents)> MyItemEvents;
I've read the links you posted but still having these doubts...
Update 2
This is more complicated to understand than I though in a first instance.
So I have like this:
OutlookAddin.h
class OutlookAddin :
public IDTExtensibility2,
public IDispEventSimpleImpl<1, OutlookAddin, &__uuidof(Outlook::ItemEvents)>
...
BEGIN_SINK_MAP(OutlookAddin)
SINK_ENTRY_INFO(1, __uuidof(Outlook::ItemEvents), 0xf002, OutlookAddin::OnItemChange, &OnSimpleEventInfo)
END_SINK_MAP()
...
void __stdcall OnItemChange();
'OnSimpleEventInfo' is defined like:
extern _ATL_FUNC_INFO OnSimpleEventInfo;
_ATL_FUNC_INFO OnSimpleEventInfo = {CC_STDCALL,VT_EMPTY,0};
then in OutlookAddin.cpp, OnConnection method:
CComPtr<Outlook::MAPIFolder> folder;
CComPtr<Outlook::_Items> items;
OutlookWorker::GetInstance()->GetNameSpacePtr()->GetDefaultFolder(olFolderContacts, &folder);
folder->get_Items(&items);
DispEventAdvise(items, &__uuidof(Outlook::ItemsEvents));
being 'OutlookWorker::GetInstance()->GetNameSpacePtr()' the _NameSpacePtr where all the environment is kept.
The expected behaviour here is to fire the function 'OnItemChange' from OutlookAddin class when an ContactItem is created/edited/deleted but that's not happening... I changed a little bit the structure to everything is in the main class OutlookAddin. Then on the function 'OnItemChange' I'll start the object of 'AutoSync' that I told you before.
Anyway I'm following the articles you gave me, really useful, thank you. Do you still have any other suggestion for me?
Thanks your patience.
Its been a while, but you should get these item events by advising for Folder.Items:
CComPtr<Outlook::MAPIFolder> folder;
// get the folder you're interested in
CComPtr<Outlook::_Items> items;
hr = folder->get_Items(&items);
hr = MyItemEvents::DispEventAdvise(items, &__uuidof(Outlook::ItemsEvents));
Where your class MyClass derives from:
IDispEventSimpleImpl<1 /*N*/, MyClass, &__uuidof(Outlook::ItemsEvents)>
And MyItemEvents is:
typedef IDispEventSimpleImpl<1 /*N*/, MyClass,
&__uuidof(Outlook::ItemsEvents)> MyItemEvents;
N identifies your sink here. Then there is the joy of the remaining macros to setup and the handler functions to implement - i refer you to this and this article for examples and to the dispinterface ItemsEvents that you can look up in oleview.exe.
Regarding update 1:
If you want to receive the events in AutoSync, implement the interface there - you are not required to sink the events to any specific instance. However, you know your design best :)
I'd just personally keep as much logic out of the central addin class as possible.
The registration code would go into some method of the class implementing the events then and called whenever it should start to receive events, while the typedef would be e.g. well placed in the class' declaration.
Regarding update 2:
From a quick glance it looks mostly right, but OnItemChange() takes one parameter - an IDispatch:
_ATL_FUNC_INFO AtlCallDispatch = {CC_STDCALL, VT_EMPTY, 1, {VT_DISPATCH}};

Dependency Injection and Runtime Object Creation

I've been trying to follow the principles of Dependency Injection, but after reading this article, I know I'm doing something wrong.
Here's my situation: My application receives different types of physical mail. All the incoming mail passes through my MailFunnel object.
While it's running, MailFunnel receives different types of messages from the outside: Box, Postcard and Magazine.
Each mail type needs to be handled differently. For example, if a Box comes in, I may need to record the weight before delivering it. Consequently, I have BoxHandler, PostcardHandler and MagazineHandler objects.
Each time a new message comes into my MailFunnel, I instantiate a new corresponding MailHandler object.
For example:
class MailFunnel
{
void NewMailArrived( Mail mail )
{
switch (mail.type)
{
case BOX:
BoxHandler * bob = new BoxHandler(shreddingPolicy, maxWeightPolicy);
bob->get_to_work();
break;
case POSTCARD:
PostcardHandler * frank = new PostcardHandler(coolPicturePolicy);
frank->get_to_work();
break;
case MAGAZINE:
MagazineHandler * nancy = new MagazineHandler(censorPolicy);
nancy->get_to_work();
break;
}
}
private:
MaxWeightPolcy & maxWeightPolicy;
ShreddingPolicy & shreddingPolicy;
CoolPicturePolicy & coolPicturePolicy;
CensorPolicy & censorPolicy;
}
On one hand, this is great because it means that if I get five different pieces of mail in, I immediately have five different MailHandlers working concurrently to take care of business. However, this also means that I'm mixing object creation with application logic - a big no-no when it comes to Dependency Injection.
Also, I have all these policy references hanging around in my MailFunnel object that MailFunnel really doesn't need. The only reason that MailFunnel has these objects is to pass them to the MailHandler constructors. Again, this is another thing I want to avoid.
All recommendations welcome. Thanks!
This looks more like a factory to me. Move the invocation of the get_to_work() method out of the invocation and return the handler. The pattern works pretty well for a factory.
class MailHandlerFactory
{
IMailHandler* GetHandler( Mail mail )
{
switch (mail.type)
{
case BOX:
return new BoxHandler(shreddingPolicy, maxWeightPolicy);
break;
case POSTCARD:
return new PostcardHandler(coolPicturePolicy);
break;
case MAGAZINE:
return new MagazineHandler(censorPolicy);
break;
}
}
private:
MaxWeightPolcy & maxWeightPolicy;
ShreddingPolicy & shreddingPolicy;
CoolPicturePolicy & coolPicturePolicy;
CensorPolicy & censorPolicy;
}
class MailFunnel
{
MailHandlerFactory* handlerFactory;
MailFunnel( MailHandlerFactory* factory ) {
handlerFactory = factory;
}
void NewMailArrived( Mail mail ) {
IMailHandler handler = handlerFactory.GetHandler(mail);
handler.get_to_work();
}
}
When you see that switch statement, think polymorphism. This design can only be extended by modification. I'd redo it in such a way that I could add new behavior by adding classes. It's what the open/closed principle is all about.
Why can't you just have three methods that are overloaded which take the different types of mail, and then do the appropriate thing? Or have each type handle itself.
In fact, if you have something like type, chances are you should in fact have different types.
Basically do the following:
1) Make the Mail class abstract.
2) Create a three sub classes of mail, Box, PostCard, and Magazine
3) Give each subclass a method to handle mail, or centralize it in a separate HandlerFactory
4) When passed to the mail funnel, simply have it call the handle mail method, or have the HandlerFactory pass it the mail, and get the appropriate handler back. Again, rather than having awkward switch statements everywhere, use the language, this is what types and method overloading is for.
If your mail handling becomes complex and you want to take it out, you can eventually make a mail handler class and extract those policies into that.
You can also consider using a template method, because the only real difference between each of those seems to be the handler you instance, maybe you could simplify it, such that the mail type determines the handler, the rest of the code is basically the same.
Interesting that you're applying dependency injection to a C++ project; it has been done elsewhere, a quick Google search finds a Google code project Autumn Framework.
But the answer by tvanfosson is what I would suggest trying first, before adopting a new framework.