2016-06-10 40 views
-1

我開發了託管C++應用程序,它將一個對象ManagedSubscription返回給C#客戶端。
ManagedSubscription接收來自C#客戶端的回調,在內部自行回調以與本機C++代碼進行通信。
雖然從原生跨越邊界到託管,我觀察到崩潰。
我已經把try-catch放在本地以及託管回調中,但它沒有被捕獲。原生到受管理邊界的CrossContext異常

這是我的託管C++代碼:

struct NativeCallbackWrapper 
     { 
     public: 
     typedef std::function<bool(const std::vector<Sample>&, bool)> Callback_t; 
     typedef bool(*CallbackPtr)(const std::vector<Sample>&, bool); 

     NativeCallbackWrapper(Callback_t callback) 
      : m_callback(callback) 
     { 
     } 

     ~NativeCallbackWrapper() 
     { 
     } 

     const Callback_t           m_callback; 
     }; 


     //Here is decalred variables in ManagedSubscription.h file 
     typedef std::function<bool(const std::vector<DFS::Chart::Misc::Sample>&, bool)> Callback_t; 
     typedef bool(*CallbackPtr)(const std::vector<DFS::Chart::Misc::Sample>&, bool); 
     delegate bool DelegateFunc(const std::vector<DFS::Chart::Misc::Sample>&, bool); 

     NativeCallbackWrapper      *m_nativeCallbackWrapper; 
     System::Action<TradeResponse, bool>^   m_callback; 
     DelegateFunc^        m_delegate; 
     System::Runtime::InteropServices::GCHandle m_delegateHandle; 


     //This object is returned to C# application 
     ManagedSubscription::ManagedSubscription(
     Action<BidAskResponse, bool>^ callback) 
     { 
     m_delegate = gcnew DelegateFunc(this, &ManagedSubscription::OnCallback); 
     m_delegateHandle = System::Runtime::InteropServices::GCHandle::Alloc(m_delegate); 
     m_nativeCallbackWrapper = new NativeCallbackWrapper(static_cast<CallbackPtr>(Marshal::GetFunctionPointerForDelegate(m_delegate).ToPointer())); 
     m_callback = callback; 
     } 

bool ManagedSubscription::OnCallback(const std::vector<Sample>& result, bool disconnected) 
    { 
    try 
    { 
     m_callback(samplesData, disconnected); 
     return true; 
    } 
    catch (Exception^ ex) 
    { 
     return false; 
    } 
    catch (Object^ ex) 
    { 
     return false; 
    } 
    } 

    //This is given to natice class which actually calls this callback (ManagedSubscription::OnCallback mentioned above) 
    const ManagedSubscription::Callback_t& ManagedSubscription::GetNativeCallback() 
    { 
    return m_nativeCallbackWrapper->m_callback; 
    } 

這是我的原生C++代碼:

KERNELBASE!RaiseException+68  cdb52105  00007ffb  00000001  
clr!RaiseTheExceptionInternalOnly+33b  cdee43f4  00007ffb  00000000  
clr!RaiseTheException+a4  cdee4460  00007ffb  00000002  
clr!RealCOMPlusThrow+69  cdeb6d72  00007ffb  43d60b70  
clr!Thread::RaiseCrossContextException+333  cdcd24cb  00007ffb  2fbadcf8  
clr!Thread::DoADCallBack+1a8  cdb69535  00007ffb  2fbade01  
clr!UM2MDoADCallBack+b3  cdb681dd  00007ffb  8a988a50  
clr!UMThunkStub+26d  bc090516  00007ffb  2fbaef70  
ManagedChartFeedInterface!DFS::Chart::HistoricalCache::TypedSubscription<DFS::Chart::ChartCache::ForexInstrumentInfo>::Publish+66 

堆棧的第一行:崩潰的

bool Publish(const std::vector<SampleType>& samples, bool disconnected) 
     { 
      try 
      { 
      //This actually calls managed callback (ManagedSubscription::OnCallback) 
      return m_subscriptionCallback(samples, disconnected); 
      } 
      catch (std::exception& e) 
      { 
      return false; 
      } 
      catch (...) 
      { 
      return false; 
      } 
     } 

這是堆棧跟蹤trace表示來自上述Publish中的本地代碼return m_subscriptionCallback(samples, disconnected);的呼叫。

我是否在回調封送中做錯了什麼?
作爲客戶端應用程序使用的應用程序域概念,它與App-Domains有關嗎?

回答

0

對於我的同一問題,我從其他站點獲得了安靜的幫助:我想在此也分享一下。以下是鏈接:

[https://msdn.microsoft.com/en-us/library/367eeye0.aspx][1]表示不需要固定代表;即使GC重新定位委託,函數指針也將保持有效。

在CoreCLR源代碼中,它看起來像Thread::DoADCallBack僅在通過END_DOMAIN_TRANSITION宏調用Thread::RaiseCrossContextException後發現了其他異常。並且Thread::DoADCallback僅在應用程序域不匹配時才使用該宏。