GXDN: Gurux Developer Network
GuruxSNMP component
This guide shows how to use Gurux SNMP component (GXSNMP) in the Visual C++ environment (C++ from now on). Source code is available at sourceforge.net
Adding GXSNMP component to the project
  1. Start Visual C++
  2. Open the project where you want to add the GXSNMP component, or create a new one
  3. Select Options from the Tools menu
  4. On Directories tab, select Executable Files to Show directories for:.
  5. Add new directory to Directories list. New path is "C:\Program Files\Common Files\Gurux\GXCom"


Select StdAfx.h file and add following lines to the bottom of the file.
	
#include <atlbase.h>
#import "GuruxSNMP.dll" raw_interfaces_only
using namespace GuruxSNMP;
#include <afxctl.h> // Needed for AfxConnectionAdvise
Now Gurux components are ready to be used from C++.


Creating components from C++
Before a new component can be used in C++, it must be created as follows:

CComPtr<IGXSNMP2> GXSNMP1; 
// Create Media Component 
HRESULT hr = ::CoCreateInstance(__uuidof(GXSNMP), 0, CLSCTX_INPROC_SERVER, 
    __uuidof(IGXSNMP2), (void**) &GXSNMP1); 

///////////////////////////////////////////////////////////// 
// Establish a connection between source and sink.
// m_dwCookie is a cookie identifying the connection, and is needed 
// to terminate the connection.
LPUNKNOWN pUnk = GetIDispatch(FALSE); 
if (!AfxConnectionAdvise(m_GXSNMP1, __uuidof(IGXSNMPEvents), pUnk, FALSE, &m_dwCookie))
{ 
    // Error.
    MessageBox("AfxConnectionAdvise Failed", "Gurux Media Sample", MB_OK | MB_ICONSTOP); 
    return FALSE;
}
Setting Media Properties
You can either select appropriate settings in the Properties dialog or edit the settings programmatically.
//Set server port and TCP/IP address. 
hr = m_GXSNMP1->put_HostName(L"Localhost"); 
// Make Error check 
hr = m_GXSNMP1->put_SNMPPort(161); 
// Make Error check 
hr = GXSNMP1->Connect(); 
// Make Error check 
// Create SNMP packet 
CComPtr<IGXSNMPPacket> pack; 
hr = ::CoCreateInstance(__uuidof(GXSNMPPacket), 0, 
    CLSCTX_INPROC_SERVER, __uuidof(IGXSNMPPacket), (void**) &pack);
// Make Error check
hr = pack->put_Command(GX_SNMP_COMMAND_GET);
// Make Error check 
// Create DataItem Component 
hr = ::CoCreateInstance(__uuidof(GXSNMPDataItem), 0, 
	CLSCTX_INPROC_SERVER, __uuidof(IGXSNMPDataItem), (void**) &Item);
// Make Error check 
hr = Item->put_OID("1.3.6.1.2.1.1.1.0"); 
// Make Error check 
CComPtr<IGXSNMPDataItems> DataItems;
hr = pack->get_DataItems(&DataItems);	
//Make Error check
hr = DataItems->Add(Item);
//Make Error check
GXSNMP1->Send(pack, NULL);
//Make Error check
Sending and receiving packets
All data is sent asynchronously. Response is received as a Received event message.
Receiving event messages
To receive event messages, notify interface must be created. Add following code to header file where notify interface is implemented.
//Add support for GXMedia component notifies
DECLARE_DISPATCH_MAP()
DECLARE_INTERFACE_MAP()
Add following code to the .cpp file where notify interface is implemented.
//Add support for GXMedia component notifies BEGIN_INTERFACE_MAP(CGuruxMediaSampleDlg,
CDialog) INTERFACE_PART(CGuruxMediaSampleDlg,
    __uuidof(IGXSNMPEvents), Dispatch) END_INTERFACE_MAP()
BEGIN_DISPATCH_MAP(CGuruxMediaSampleDlg,
		
CCmdTarget) DISP_FUNCTION_ID(CGuruxMediaSampleDlg,
    "OnReceived", 1, OnReceived, VT_EMPTY, VTS_VARIANT VTS_WBSTR) DISP_FUNCTION_ID(CGuruxMediaSampleDlg,
    "OnError", 2, OnError, VT_EMPTY, VTS_WBSTR) END_DISPATCH_MAP()
/////////////////////////////////////////////////////////////////////////////

//Handle
received data /////////////////////////////////////////////////////////////////////////////
HRESULT CGuruxMediaSampleDlg::OnReceived(VARIANT Data, BSTR SenderInfo)
{
    if (Data == NULL) 
    {
        return E_INVALIDARG;
    }
    CComPtr<IGXSNMPDataItem> msg;
    CComVariant var;
    //Get message.
    if(FAILED(hr = Data.punkVal->QueryInterface(&msg))) 
    {
        //Handle error 
        return hr; 
    }
    //Get SNMP data. 
    if (FAILED(hr = msg->get_Data(&var)) ||
        FAILED(hr = var.ChangeType(VT_BSTR)))
    {
        //Handle error
        return hr;
    }    
    //Update data.
    m_dataReceived +=var.bstrVal;
    m_sender = SenderInfo;
    UpdateData(FALSE);
    return S_OK;
}

/////////////////////////////////////////////////////////////////////////////
// Show occurred error
/////////////////////////////////////////////////////////////////////////////
HRESULT CGuruxMediaSampleDlg::OnError(BSTR ErrorInfo)
{
    USES_CONVERSION;
    MessageBox(W2T(ErrorInfo), "Gurux Media Sample", MB_OK | MB_ICONERROR);
    return S_OK;
}
Error Handling
It's very important to consider error handling when sending and receiving data. The connection can drop down, or something else unexpected may happen. If something unwanted happens, Gurux SNMP component returns error. The following example shows how to handle errors in C++.
////////////////////////////////////////////////////////////////////////////////
// This method helps you to see in text form what error GXCom returned.
CString GetGXError(IUnknown* pUnknown)
{
    CString errStr;
    if (pUnknown == NULL)
    {
        return errStr;
    }
    CComPtr<ISupportErrorInfo> pSupportErrorInfo = NULL;
    CComPtr<IErrorInfo> pErrorInfo = NULL;
    HRESULT hr = pUnknown->QueryInterface(IID_ISupportErrorInfo, (void**) &pSupportErrorInfo);
    if (FAILED(hr))
    {
        return errStr;
    }
	
    //If interface doesn't support error info don't go further.
    if (FAILED(pSupportErrorInfo->InterfaceSupportsErrorInfo(IID_IUnknown)))
    {
        return errStr;
    }
	
    // Get the current error object. Return if no error object exists.
    GetErrorInfo(0,&pErrorInfo);
    if (pErrorInfo == NULL) 
    {
        return errStr;
    }
			
    //Get error description
    CComBSTR err;
    pErrorInfo->GetDescription(&err);
    errStr = err;
    return errStr;
}

//////////////////////////////////////////////////////////////////////////////// 
// Create Media Components
void CreateComponents()
{
    if(FAILED(::CoCreateInstance(__uuidof(GXSNMP), 0,
            CLSCTX_INPROC_SERVER,
            __uuidof(IGXSNMP),
            (void**) &m_GXSNMP1)))
    {
        //Show Error if any
        MessageBox(GetGXError(m_GXSNMP1), "Gurux Media Sample", MB_OK | MB_ICONERROR);
    }

    ///////////////////////////////////////////////////////////// 
    //Establish a connection between source and sink. 
    //m_dwCookie is a cookie identifying the connection, and is needed 
    //to terminate the connection. 
    LPUNKNOWN pUnk = GetIDispatch(FALSE); 
    if (!AfxConnectionAdvise(m_GXSNMP1, __uuidof(IGXSNMPEvents), pUnk, FALSE, &m_dwCookie)) 
    {
        // Error. MessageBox("AfxConnectionAdvise Failed", "Gurux Media Sample", MB_OK | MB_ICONSTOP);
        return FALSE; 
    }
}

//////////////////////////////////////////////////////////////////////////////// 
// Close Media Components
void CloseComponents()
{
    LPUNKNOWN pUnk = GetIDispatch(FALSE); 
    /////////////////////////////////////////////////////////////
    //Release sink. 
    //Terminate a connection between source and sink. 
    //m_pUnkSrc is IUnknown of server obtained by CoCreateInstance(). 
    //m_dwCookie is a value obtained through AfxConnectionAdvise(). 
    if (!AfxConnectionUnadvise(m_GXSNMP1 , __uuidof(IGXSNMPEvents), pUnk, FALSE, m_dwCookie)) 
    {
        // Error. 
        MessageBox("AfxConnectionAdvise Failed", "CPP Sample", MB_OK | MB_ICONSTOP); 
    } 
			
    //Release Components when application is closing. 
    m_GXSNMP1 = NULL; 
    CoUninitialize(); 
}
Using the components from development environment

Using from .NET | Using from Visual Basic | Using from C++