Using Message Queuing COM Components in Visual C++ and C

 

Applies To: Windows 10, Windows 7, Windows 8, Windows 8.1, Windows Server 2008, Windows Server 2008 R2, Windows Server 2012, Windows Server 2012 R2, Windows Server Technical Preview, Windows Vista

Message Queuing COM objects can be invoked using Visual C++® and C/C++. Although both languages can be used, the examples in the Message Queuing SDK use Visual C++ because of its Visual Basic like syntax.

Note

Visual C++ code imports the Mqoa.dll file using the #import directive to permit the use of smart pointers. The #import directive generates two files that contain smart-pointer declarations for all Message Queuing objects: Mqoa.tlh and Mqoa.tli. The .tli file is included by a #include directive in the .tlh file, which is processed by the compiler as if it were named by a #include directive in your application. Smart pointers provide an easy-to-use syntax that is similar to the syntax provided by Visual Basic. This syntax provides:

  • HRESULT to exception mapping. A COM-based application can use try and catch to handle errors instead of testing for return values.

  • Support for optional parameters (not available in C/C++ implementations).

  • Reference counting and QueryInterface support, so there is no need for explicit AddRef/Release calls.

    Before using any smart pointer, your application must call CoInitialize or CoInitializeEx to initialize the COM library. After the COM library is no longer needed, your application must call CoUnitialize.

    When smart pointers are used to expose properties or methods that were introduced in MSMQ 2.0 or MSMQ 3.0 or to implement certain features that were introduced in MSMQ 2.0 or MSMQ 3.0, you must create a smart pointer to the appropriate interface. For example, you must use a smart pointer to the IMSMQApplication3 interface to expose the MSMQApplication.ActiveQueues property and MSMQApplication.Connect method (introduced in MSMQ 3.0) of the MSMQApplication object, and you must use a smart pointer to the IMSMQMessage3 interface to expose the MSMQMessage.Send method of the MSMQMessage object if your application sends messages to a single queue or multiple queues represented by an MSMQDestination object (introduced in MSMQ 3.0).

    On the other hand, the properties and methods of the objects that were introduced in MSMQ 3.0 are exposed by the original interface. For example, use a smart pointer to the IMSMQCollection interface to expose the MSMQCollection.Item method of the MSMQCollection object.

    Do not include the Mqoai.h header file when you import Mqoa.dll.

Here are two code fragments that illustrate some of the differences between Visual C++ and C/C++ code. Both fragments create a public queue.

Visual C++

#import "mqoa.dll";  
using namespace MSMQ;  
  
   try {  
       IMSMQQueueInfoPtr pqinfo ("MSMQ.MSMQQueueInfo");  
       pqinfo->PathName = L".\\queuename";  
       //  
       // Create nontransactional, non-world-readable queue.  
       //  
       pqinfo->Create();  
       }  
   catch (_com_error &e) {  
        // UNDONE: handle error.  
       }  
Using C/C++  
    IMSMQQueueInfo *pqinfo;  
  
    HRESULT hresult;  
    VARIANT varIsTransactional;  
    VARIANT varIsWorldReadable;  
    //  
    // Create MSMQQueueInfo object  
    //  
    hresult = CoCreateInstance(  
                   CLSID_MSMQQueueInfo,  
                   NULL,                    // punkOuter  
                   CLSCTX_SERVER,  
                   IID_IMSMQQueueInfo,  
                   (LPVOID *)&pqinfo  
                   );  
    if (SUCCEEDED(hresult)) {  
      // Set PathName.  
      pqinfo->put_PathName(L".\queuename");  
      //  
      // Specify whether it is transactional.  
      //  
      VariantInit(&varIsTransactional);  
      varIsTransactional.vt = VT_BOOL;  
      varIsTransactional.boolVal = MQ_TRANSACTIONAL_NONE;  
      VariantInit(&varIsWorldReadable);  
      varIsWorldReadable.vt = VT_BOOL;  
      varIsWorldReadable.boolVal = FALSE;  
      //  
      // create the queue  
      //  
      hresult = pqinfo->Create(&varIsTransactional,   
                               &varIsWorldReadable);  
      //  
      // UNDONE: need to handle failure...  
      //  
    }