简体   繁体   中英

c++ native code DLL using an abstract class into a wrapper to be used in C# module

Hi i am having the same problem with abstract class.i am trying to wrap my cpp Dll calls to use in the C# module.

Dll is using the Factory pattern.which contain a class Factory,MiddileWare ,And their co strong text rresponding child class.Could any one help me to start the wrapper. i am stuck in between this.Your help will be appreciated. i am giving the flow 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 expose the rabbitMq class functions[Connect,send,Recieve ete from MiddleWareConnection.h to C# module.

Thanks

below I posted a small code example of a wrapping C++/CLI class. You could create a new C++/CLI project which links your native library and create a class following the example below. This will produce a managed assembly that you could reference from C# side. Hope it 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;

};

****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.

****Wrapper****

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 a managed type to an unmanaged type

 } 

instead of this we are using createinstance() [InitializeRBMQ() is inside connect(),so it will be handled inside i think]

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);

}

i tried one example with CPPMath class.In real i am attaching 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............

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM