CPPREST SDK integration into MFC Application built using VS 2010

Mar 26, 2014 at 2:05 PM
I have MFC application built using VS 2010 SP1 that produces some analytics and shows it to the user

I would like to integrate CPP REST library into this project and turn this into service and return computed analytics as JSON payload as REST message

Let me know if REST SDK can be integrated into an MFC application

Thanks
Kedar
Coordinator
Mar 26, 2014 at 8:13 PM
Hi

We had support for VS2010 until our 1.2 release. Now, we support only two versions of Visual Studio (VS2012 and VS2013).
REST SDK can be integrated to any MFC application, however we don't provide binaries or build files for VS2010.
If you are unable to update to 2012 or 2013, you can still continue to use our 1.2 or any prior releases.

Thanks
Kavya
Apr 3, 2014 at 1:54 PM
Kavya,

Thanks for getting back to me on this

I was able to use VS2012 and integrate REST SDK with MFC app and it works fine as long as there is no interactivity

This MFC App that I have is Dialog based App with few widgets ( Listboxes )

When the REST message arrives, I try to get handle to the Dialog and write something to those widgets and the Application simply hangs and doesn't go further

For instance, for every REST request, I want to display the Request header on the Listbox and then proceed to handle the REST message

void handle_post(http_request request)
{
 ...
 theApp.m_pDlg->m_ListBox.AddString ( "#Received new request from Client. Processing..." );  // This hangs
 ...
)

I am using REST SDK 1.3.1

Let me know if you have faced any issues with UI interaction while dealing with REST SDK in general

Thanks
Kedar
Coordinator
Apr 4, 2014 at 2:19 AM
Hi Kedar

We have not heard of any issues with UI interaction.
We can look into this further if you could share a minimal repro of the issue.
If you won't want to share with everyone on the forums you can send it directly to me by contacting me at kavyako at Microsoft dot com.

Thanks
Kavya.
Apr 6, 2014 at 10:57 AM
Hi Kedar,
I have been using Casablanca in Win32 projects (WTL). I am not an expert in either Win32 or Casablanca, but here's my two cents in case it helps.

I believe the problem you are seeing is related to threading. The key point here is that Casablanca calls (or is very likely to call) handler methods like handle_post on threads other than the main (UI) thread.

In all UI frameworks I can think of (including MFC) it is not allowed to interact with the UI directly from background threads. In particular in Win32:
  • Controls have what is called 'thread affinity', which in short means that the system stores some or all of their windows-related data in thread local storage, so directly accessing the controls from background threads simply doesn't work as expected. This is not what is happening in your case though (SendMessage is used under the covers, see below), nor would it cause hangs.
  • Call like m_ListBox.AddString are implemented using SendMessage() calls in frameworks like WTL and MFC. SendMessage is a blocking function and it is a bad idea to be issuing calls to it from background threads. This is WTL's implementation (MFC's will be quite similar):
    // manipulating listbox items
    int AddString(LPCTSTR lpszItem)
    {
        ATLASSERT(::IsWindow(m_hWnd));
        return (int)::SendMessage(m_hWnd, LB_ADDSTRING, 0, (LPARAM)lpszItem);
    }
The key for your program to function correctly is to replace the SendMessage() call with PostMessage(). For example
  1. You could directly call PostMessage([hwnd of target control], LB_ADDSTRING,...) but this has problems related to the lifetime of the string parameter.
  2. You can define custom window messages for communicating with the UI of your application (sort of an interface) and use PostMessage to send them to your UI thread.
I prefer the second method (this is what I have been doing and I have seen no problems) because it leads to cleaner structure of your application. You can define wrapper methods (members of your main window) that internally call PostMessage.

Of course you need to be careful when calling PostMessage with parameters such as strings. Exactly because you message is being pushed in a queue (that is, it is not processed synchronously) all parameters need to be valid not only at the point where PostMessage is called but also at the point where the message is actually processed (via the message map of the window). If you follow the wrapper methods approach, you can new up a string on the call site and delete it on the receiving end or use WM_COPYDATA (see here http://stackoverflow.com/questions/10619301/sending-receiving-a-string-through-postmessage). I find the first approach simpler and this is what I have been using.

This is one of the cases we still need to explicitly use new and delete in new C++ applications, but then again Win32 is a pretty old framework. Of course with a bit of work you can wrap up everything pretty nicely.

Note that this is not a Casablanca-specific issue. You are likely to run into similar problems if you directly use PPL (or pplx that comes with Casablanca) or std::thread or _beginthread().

Cheers,
Yiannis
Apr 9, 2014 at 1:21 PM
Yiannis,

Thanks for the detailed explanation on this

I will make changes based on your recommendations to address this issue

Thanks
Kedar