none
Problem communicating C++ app with Asp .NET solution using WCF RRS feed

  • Pergunta

  • Could someone help me?

    I’m creating a vc++ app based on native class that receive device events from the API.

    The problem is that I need to communicate this app with an Asp.NET solution, so I’m using WCF.

    As WCF uses managed class and API uses native class, the solution is not working.

    My code:

    //************************************************************************//  
    API.h
    class NativeClass;
    typedef TEventHandler< NativeClass, INACServer, _INACServerEvents> INACServerEventHandler;
     
    class NativeClass
    {
    public:
     
        NativeClass ();
     
        HRESULT NativeClass::OnEventReceivedFromAPI
        (
         INACServerEventHandler* pEventHandler,
         DISPID dispidMember,
         REFIID riid,
         LCID lcid,
         WORD wFlags,
         DISPPARAMS* pdispparams,
         VARIANT* pvarResult,
         EXCEPINFO* pexcepinfo,
         UINT* puArgErr
        );
        INACServerPtr m_spINACServer; 
        INACServerEventHandler *m_pINACServerEventHandler;
        int OnBnClickedButtonInitializeServer();
        int OnBnClickedButtonStartServer();
    };
    //************************************************************************//  
    API.c
    NativeClass * pCNtg;
     
    int NativeClass::OnBnClickedButtonInitializeServer()
    {   
     
        m_spINACServer.CreateInstance( __uuidof( NACServer ) );
     
        INACServer *pInterface = m_spINACServer.GetInterfacePtr();
       
       
        HRESULT hr = pInterface->InitializeServer( lThreadNum, lTerminalCount,lReadBufferMax, lIOReadBufferMax, lWriteBufferMax, lIOWriteBufferMax );
       
     
        return hr;
     
       
    }
    int NativeClass::OnBnClickedButtonStartServer()
    {
     
        INACServer *pInterface = m_spINACServer.GetInterfacePtr();
       
        HRESULT hr = pInterface->StartServer( wszBuffer, lPort );
       
        m_pINACServerEventHandler = new INACServerEventHandler( *this, m_spINACServer, & NativeClass:: OnEventReceivedFromAPI);
       
        return hr;
    }
    HRESULT NativeClass:: OnEventReceivedFromAPI( INACServerEventHandler* pEventHandler, DISPID dispidMember,
         REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult, EXCEPINFO* pexcepinfo, UINT* puArgErr )
    {
        //event received from terminal
        return S_OK;
    }  
    //************************************************************************//  
    WCF.h
    [ServiceContract]
    interface class IFoo
    {
        [OperationContract]
        int Init();
      
        [OperationContract]
        int Start();
    };
    ref class Foo : IFoo
    {
    public:
        static ServiceHost^ host;
        virtual int Init()
        {
           pCNtg = new NativeClass();
           return = pCNtg->OnBnClickedButtonInitializeServer();
        }   
        virtual int Start()
        {
           return pCNtg->OnBnClickedButtonStartServer();
        }
    }; 
    //************************************************************************// 
    
    

    So the Asp.NET app calls Init() and Start() WCF functions that initialize the device, so it calls the function NativeClass:: OnEventReceivedFromAPI to send device events to app.

    With the code above the app runs, but the function OnEventReceivedFromAPI is never called by the device.

    The problem could be fixed changing the code above to the code bellow:

        virtual int Init()
        {
           return NativeClass::OnBnClickedButtonInitializeServer();
        }   
       
        virtual int Start()
        {
           return NativeClass::OnBnClickedButtonStartServer();
        }
    
    

     I know this change could solve the problem, because if I call NativeClass::OnBnClickedButtonInitializeServer();  andNativeClass::OnBnClickedButtonStartServer(); from another NativeClass function, it works.

    However with this change, compiler shows error C2352 illegal call of non-static member function.

    So I can instance the Native class to call from a managed class, however the API don’t call the function OnEventReceivedFromAPI .

    How to implement this?

    Thanks.

    sexta-feira, 15 de abril de 2011 13:50

Todas as Respostas

  • aljodAv.BR muito obrigado pela ajuda. Estou retornando o HR, para que ele seja tratado na aplicação que chama o WCF e não no C++, mas o valor retornado é sempre zero (S_OK). O código está retornando zero como se tudo estivesse correto, só que a API não chama a função de evento.

    segunda-feira, 18 de abril de 2011 13:41
  • aljodAv.BR,

    Primeiramente agradeço pela sua resposta.

    Estou trabalhando com o Fabio nesse projeto e vou responder a sua pergunta:

    São 2 programas rodando em paralelo, o c++ é quem vai utilizar esse ponteiro “ m_pINACServerEventHandler ”, o Asp.NET não precisa.

    A chamada:

     m_pINACServerEventHandler = new INACServerEventHandler( *this, m_spINACServer, &NativeClass:: OnEventReceivedFromAPI);
    
     
     
    Faz com que o programa imediatamente receba do terminal um evento que chama a função abaixo com o dispidMember = 0x01 (que é a solicitação de conexão do terminal):
    HRESULT NativeClass:: OnEventReceivedFromAPI( INACServerEventHandler* pEventHandler, DISPID dispidMember,
       REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult, EXCEPINFO* pexcepinfo, UINT* puArgErr )
     
    Nós temos convicção de que essa parte do código está correta, pois se chamados as 2 funções OnBnClickedButtonInitializeServer e OnBnClickedButtonStartServer de dentro de uma outra função pertencente a mesma classe NativeClass, a função OnEventReceivedFromAPI é chamada.
    Isso é constatado quando criamos a função abaixo que é chamada através de um menu da aplicação MFC:
    void NativeClass::OnAppDebug()
    {
      int resp = NativeClass::OnBnClickedButtonInitializeServer();
      int resp1 = NativeClass::OnBnClickedButtonStartServer();
    }
    
    Conclusão:
    - Se chamamos as funções de inicialização de dentro da mesma classe NativeClass o código funciona.
    - Quando tentamos chamá-la de dentro da classe gerenciada, o compilador não permite chamar da mesma forma "NativeClass::OnBnClickedButtonStartServer()" e é necessário instanciá-la:
    NativeClass *pCNtg = new NativeClass();
    pCNtg->OnBnClickedButtonInitializeServer();
    pCNtg->OnBnClickedButtonStartServer();
    
    Ao fazer isso, a função OnEventReceivedFromAPI nunca é chamada.
    Por fim, perceba que a função que cria o evento:
    m_pINACServerEventHandler = new INACServerEventHandler( *this, m_spINACServer, &NativeClass:: OnEventReceivedFromAPI);
    

    Passa para o driver o endereço da função que será chamada "&NativeClass:: OnEventReceivedFromAPI" e o fato de estarmos instanciando a classe através da variável "pCNtg" pode estar causando o problema.
    Temos solução para isso?

    Eduardo-SP-BR
    terça-feira, 19 de abril de 2011 17:24
  • A declaração "NativeClass * pCNtg;" estava no arquivo API.c, movi para o WCF.h , mas o resultado foi o mesmo.

    Tenho a impressão que o problema está na sequência:

    NativeClass * pCNtg;
    pCNtg = new NativeClass();
    return = pCNtg->OnBnClickedButtonInitializeServer();
    

    Você tem alguma sugestão de como fazer isso?

     Abs,

          


    Eduardo-SP-BR
    quinta-feira, 21 de abril de 2011 20:06
  • #include "API.h"
    
    NativeClass * pCNtg;
    
    [ServiceContract]
    interface class IFoo
    {
      [OperationContract]
      int Init();
     
      [OperationContract]
      int Start();
    };
    ref class Foo : IFoo
    {
    public:
      static ServiceHost^ host;
      virtual int Init()
      {
        pCNtg = new NativeClass();
        return = pCNtg->OnBnClickedButtonInitializeServer();
      }  
      virtual int Start()
      {
        return pCNtg->OnBnClickedButtonStartServer();
      }
    };
    

    Eduardo-SP-BR
    domingo, 24 de abril de 2011 22:55