2013-04-10 157 views
4

我想知道從C++代碼調用c#代碼的最佳做法是什麼?我想要的是:我已經編寫了C++代碼,當用戶使用該程序並在C++代碼中遇到某些函數時,我想調用另一個c#代碼來執行其他操作,所以它像語言之間的代理一樣。我怎麼能最好地完成這個?我到目前爲止的想法是:在C#中,我可以製作Web服務,然後用C++調用它。從C++調用C#事件

+1

考慮讓C#類成爲COM對象,以便您可以直接從C++中調用它 – 2013-04-10 11:35:01

回答

2

這裏的解決方案使用C++\Cliboost::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++中使用它們。