C ++ native code DLL using abstract class wrapped to be used in C # module

Hi I have the same problem with an abstract class. I am trying to wrap my cpp DLL calls for use in a C # module.

Dll uses Factory pattern which contains Factory class, MiddileWare and corresponding strong child class . Can anyone help me start the shell. I'm stuck in between. Your help will be appreciated. I give a stream here:

MiddleWareFactory.h

#pragma once
#include "MiddleWareConnection.h"
#include "std afx.h"

  #ifdef MIDDLEWAREFACTORY_EXPORTS
#define MIDDLEWAREFACTORY_API __declspec(dllexport)
#else

      

#define MIDDLEWAREFACTORY_API __declspec (dllimport) #endif

  MIDDLEWAREFACTORY_API enum eMiddleWareEngine
      {
          eRabitMQ = 0,  
          eZeroMQ,                           
          eActiveMQ          

        };
     // This class is exported from the MiddleWareFactory.dll

      class MIDDLEWAREFACTORY_API CMiddleWareFactory
      {
      public:
         CMiddleWareFactory(void);
         ~CMiddleWareFactory();
        // TODO: add your methods here.

        //Function to Create the  object of Broker module:implemnted the                   Factory   concept.
      BOOL CreateInstance(CMiddleWareConnection** pMObj);
     int m_eMomEngine;//To define which MOM need to enable.

};



extern MIDDLEWAREFACTORY_API int nMiddleWareFactory;

MIDDLEWAREFACTORY_API int fnMiddleWareFactory(void);

      

MiddleWareConnection.h

#pragma once

class CMiddleWareConnection {public:

  virtual ~CMiddleWareConnection(void)
  {
   }
  //Pure virtual fuctions for interfacing 
  virtual BOOL Connect(int nServerType)=0;
   virtual BOOL CreateSessionExchange() = 0;
   virtual BOOL CreateQueue(LPCTSTR lpszQueueName) = 0;
   virtual BOOL Disconnect() = 0;
   virtual BOOL Send(void *MomItem,LPCTSTR lpszKey, int               &nSendCount)=0;
   virtual BOOL Receive() = 0;
   virtual void StopReceiver() = 0;
   virtual void GetData(void* pMsg, int &nMsgLen,int nMsgType,int &nReceiveCount)=0;
   };

      

RabbitMQ.h

  #pragma once
  #include "MiddleWareConnection.h"
  #include "Amqp.h"
  #pragma comment(lib, "rabbitmq.4.lib")
  #define GET_DATA(a){memcpy(&a, pDataPtr,  sizeof(a));pDataPtr+=sizeof(a);}
  #define GET_DATA_EX(s,n){memcpy(s, pDataPtr, n);pDataPtr+=n;}

 typedef struct _ROUTINE_KEY
{
 CString RoutingKey;             

 }ROUTEKEY, *LPROUTEKEY;

   class CRabbitMQ :
   public CMiddleWareConnection
      {
          public:

      CRabbitMQ(CAppConfig &rConfig);
     ~CRabbitMQ();
      void   InitializeRBMQ(CAppConfig &rConfig);//Initialize RBMQ Config;
         BOOL   Connect(int nServerType);
         BOOL   Disconnect(void);
         BOOL   Send(void *MomItem, LPCTSTR lpszKey, int &nSendCount);
         BOOL   Receive(void);
         BOOL   CreateQueue(LPCTSTR lpszQueueName);
         BOOL   CreateSessionExchange();
         BOOL   BindQueue(LPCTSTR lpszQueue, LPCTSTR lpszExchangeName, LPCTSTR lpszKey);
         bool   IsConnected(){return m_bConnected;}
         void   SetKeyQueueCombination( TCHAR *pszQueueName, TCHAR *pszRoutingKey);
         void   StopReceiver();
         bool   ReEstablishRMQMWConnection();
        void   GetData(LPBYTE &pMsg, int &nMsgLen,int &nReceiveCount);
        void   GetData(void* pMsg, int &nMsgLen,int nMsgType,int &nReceiveCount);
     BOOL   GetNext_JasonListItem(LPJASON_ITEM pItem);
      LPRABBIT_MQ_ITEM GetNextItem();

      };

      

Here I want to show the functions of the rabbitMq class [Connect, Send, Get ete from MiddleWareConnection.h in C #.

thank

+3


source to share


3 answers


below I posted a small sample code for a C ++ / CLI class. You can create a new C ++ / CLI project that will link your own library and create the following class. This will create a managed assembly that you could reference from the C # side. Hope this helps!



#include <Windows.h>
#include <vcclr.h>  

using namespace System;
using namespace System::Text;
using namespace System::Collections::Generic;
using namespace System::Runtime::InteropServices;

public ref class CMiddleWareConnection_Net
{
  public:

    CMiddleWareConnection_Net()
    {
        pMiddleWareConnection = NULL;
    }

    ~CMiddleWareConnection_Net()
    {
        //Release pMiddleWareConnection
        if (pMiddleWareConnection)
            delete pMiddleWareConnection;
    }

    void   InitializeRBMQ(CAppConfig_Net config)
    {
        // CAppConfig_Net is another ref class 
        // which provides a toNative method 
        // returning a plain C++ CAppConfig object
        CAppConfig rConfig = config.toNative();  

        pMiddleWareConnection = CRabbitMQ(rConfig);
    }

    bool   Connect(int nServerType)
    {
        return (pMiddleWareConnection->Connect(nServerType) == TRUE);
    }

    bool   Disconnect(void)
    {
        return (pMiddleWareConnection->Disconnect() == TRUE);
    }

    bool   Send(array<Byte>^ MomItem, String^ lpszKey, int% nSendCount)
    {
        //Assuming MomItem is a byte array...
        unsigned char *pData = new unsigned char[MomItem->Length];
        Marshal::Copy(MomItem, 0, IntPtr(pData), MomItem->Length);          

        //Marshal String^ to LPCSTR
        IntPtr ip = Marshal::StringToHGlobalAnsi(lpszKey);  
        LPCSTR str = static_cast<LPCSTR>(ip.ToPointer());

        bool bRet = (pMiddleWareConnection->Send(pData, str, nSendCount) == TRUE);

        //Freeing memory
        delete[] pData;
        Marshal::FreeHGlobal(ip);

        return bRet;
    }

    bool   Receive(void)
    {
        return (pMiddleWareConnection->Receive() == TRUE);
    }

    /* Other methods */
    ... 

  private:
    CMiddleWareConnection *pMiddleWareConnection;

};

      

0


source


**** MiddleWareFactory.h ****

     BOOL CreateInstance(CMiddleWareConnection** pMObj)
        { 
          //if( some config value)
            *pMObj = new RabbitMq();
          // esle
               /***other MOm like OBCS,OSCS etec...**/

        }

      

**** **** MiddlewareConnection.h

  have the basic abstract functions....

**Rabbitmq.h**

it is one of the child class.

      

**** **** Packing

CLRWrapper::CppMathWrapper::CppMathWrapper()
{
    cppMath = new cCppMath();
    oFact->createInstance(&cppMath);'// here i want to pass the reference & wanna get back the child class type:now i am stuck here..how can we pass/marshal the object:im getting the error

} 
BOOL CLRWrapper::CppMathWrapper::connect(type)
{
  return (cppMath->Connect(nServerType) == TRUE);
}

..........And so On............

      



CLR Wrapper.cpp (11): error C2664: 'Factory :: createInstance': cannot convert parameter 1 from 'cli :: interior_ptr' to 'Base **' 1> with 1> [1> Type = cCppMath * 1> ] 1> Cannot convert managed type to unmanaged type

}

      

instead we use createinstance () . [InitializeRBMQ () is inside connect (), so it will be handled internally I guess]

void   InitializeRBMQ(CAppConfig_Net config)
    {
    // CAppConfig_Net is another ref class 
    // which provides a toNative method 
    // returning a plain C++ CAppConfig object
    CAppConfig rConfig = config.toNative();  

    pMiddleWareConnection = CRabbitMQ(rConfig);
}

      

C # side I want to expose:

private static void Main(string[] args)
{
CppMathWrapper wrapper = new CppMathWrapper();
wrapper.connect(0);

      

}

0


source


I tried one example with the CPPMath class. In reality, I am adding the code below:

CLRWrapper::CppMathWrapper::CppMathWrapper()
{
   middlewareConnection *oConn;// MiddleConnection.h pointer
   middleWareFactory oFact= new middleWareFactory ();//  MiddleWareFactory.h object
   oFact->createInstance(&oConn);'// here i want to pass the reference & wanna get back the child class type:now i am stuck here..how can we pass/marshal the object:im getting the error.How could i wrap the object....the same like 

}                                                                                                                                           
BOOL CLRWrapper::CppMathWrapper::connect(type)
{
  return (oConn->Connect(nServerType) == TRUE);
}

..........And so On............

      

0


source







All Articles