2016-06-10 12 views
-1

ManagedSubscription의 개체를 C# 클라이언트에 반환하는 관리되는 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-domain 개념을 사용함에 따라 App-Domains와 관련이 있습니까?

답변

0

나는 내 동일한 문제에 대해 다른 사이트로부터 도움이되는 조용한 대답을 얻었습니다. 여기에 대한 링크가 있습니다 :

[https://msdn.microsoft.com/en-us/library/367eeye0.aspx][1]은 대표를 핀일 필요가 없다고 말합니다. GC가 대리자를 재배치하더라도 함수 포인터는 유효합니다.

CoreCLR 소스에서 다른 예외가 발견 된 후 END_DOMAIN_TRANSITION 매크로를 통해서만 Thread::DoADCallBackThread::RaiseCrossContextException으로 호출됩니다. Thread::DoADCallback은 응용 프로그램 도메인이 일치하지 않는 경우에만 해당 매크로를 사용합니다.