2013-04-10 4 views
4

Я хотел бы знать, что лучше всего использовать для вызова кода C# из кода на C++? То, что я хочу точно: я уже написал код C++, и когда пользователь использует эту программу и сталкивается с определенными функциями в коде C++, я хочу вызвать другой код C#, чтобы выполнить что-то еще, так что это как делегирование между языками. Как я мог бы это сделать? Моя идея до сих пор: в C# я могу сделать веб-сервис, а затем вызвать его с помощью C++.Вызов C# события из C++

+1

Рассмотрите возможность создания класса C# COM-объекта, чтобы вы могли вызвать его непосредственно из C++ –

ответ

2

здесь является решение с использованием C++\Cli и boost::function

нативный код:

typedef void MemberFunctionPointerType(int x); 

class NativeClass 
{ 
public: 
    //I used boost but any function pointer will work 
    void setDelegate(boost::function<MemberFunctionPointerType> delegate) 
     { 
      m_delegate = delegate; 
     } 
    void DoSomeThing() 
     { 
      int x; 
      //do your logic here 
      ... 
      ... 
      ... 
      //when the needed event occurs call the callbackfunction so the class which registered to event will get his function called. 
      m_delegate(x);      

private: 
    boost::function<MemberFunctionPointerType> m_delegate;   

};   

управляемый код:

typedef MemberFunctionPointerType* CallbackFunctionType; 
delegate void CallbackFuncDelegate; 

class ManagedClass 
{ 
public: 
    ManagedClass() 
    { 
     m_delegate = gcnew CallbackFuncDelegate(this,&ManagedClass::CallBackFunction); 
     m_native = new NativeClass(); 

     //register the delegate; 
     boost::function<MemberFunctionPointerType> funcPointer(static_cast<CallbackFunctionType>(Marshal::GetFunctionPointerForDelegate(m_delegate).ToPointer())); 
     m_native->setDelegate(funcPointer); 
    } 
    //the callback function will be called every time the nativeClass event occurs. 
    void CallBackFunction() 
    { 
     //do your logic or call your c# method 
    } 

private: 
    CallbackFuncDelegate^ m_delegate ; 
    NativeClass* m_native;  
}; 

Так почему же эта работа и сборщик мусора не разрушает все : Есть вопросы, о которых стоит беспокоиться при работе с GC:

1) Сбор делегата: Делегат не будет собран до тех пор, пока ManagedClass жив. Поэтому нам не нужно беспокоиться об этом.

2) Перераспределение: GC может перераспределить объект в памяти, как только он будет, но нативный код не получит прямой указатель на делегат, а скорее указатель на некоторый фрагмент кода, созданный маршаллером. Это косвенное указание гарантирует, что нативный указатель функции остается в силе, даже если делегат перемещается.

3

Я предлагаю экспортировать классы C# в качестве видимых классов com. Затем используйте их в C++.

1

Попробуйте использовать Unmanaged Exports. Я лично использую его для вызова функций C# из собственного приложения на C++.