2013-03-27 5 views
7

हाय स्टैक ओवरफ़्लो के सदस्यों पर E_NOINTERFACE साथ विफल रहता है,QueryInterface सी #

मैं सी # प्रोग्रामिंग करने के लिए एक नौसिखिया हूँ। मैं एक बुनियादी कैमरा स्ट्रीमिंग विकसित कर रहा हूं और अभी भी एप्लिकेशन को कैप्चर कर रहा हूं। एक बार उपयोगकर्ता अभी भी ले लेता है, तो मैं इसे VMR9 की बिटमैप मिश्रण अवधारणा का उपयोग करके ओवरले पर प्रदर्शित करूँगा।

मैंने क्या किया?

  • मैं से here
  • पहले सी # प्रत्यक्ष शो पुस्तकालय का इस्तेमाल कर रही हूँ मैं सभी आवश्यक फिल्टर इंटरफेस मिलता है। संलग्न कैप्चर डिवाइस खोजें। पूर्वावलोकन पिन के लिए स्रोत फ़िल्टर और vmr9 के साथ रेंडर स्ट्रीम कहा जाता है। स्टाइल पिन के लिए स्रोत फ़िल्टर, नमूना हथियार और शून्य रेंडरर।
  • मेरे पास तीन मेनू बटन हैं -> अभी भी ले लो, ओवरले दिखाएं और ओवरले छुपाएं।
  • मैं उस पुस्तकालय में प्रदान किए गए बिटमैप मिक्सर नमूने का उपयोग कर रहा हूं।
  • हर बार जब उपयोगकर्ता प्रेस स्टिल मेनू दबाता है, तो छवि डेस्कटॉप में सहेजी जाएगी और इसे छोटे रिज़ॉल्यूशन में फिर से आकार दिया जाएगा और वीडियो ओवरले पर प्रदर्शित किया जाएगा।
  • ओवरले दिखाएं और ओवरले कॉल छुपाएं ShowHideBitmap() जो vmr9 फ़िल्टर से VMR9BitmapMixer इंटरफ़ेस क्वेरी करने का संचालन करता है, VMR9AlphaBitmap संरचना भरता है और फिर IVMRMixerBitmap9.SetAlphaBitmap फ़ंक्शन को कॉल करता है।

मुझे किस समस्या का सामना करना पड़ता है?

  • अभी भी लेने के बाद, अगर मैं मेनू विकल्प के माध्यम ShowHideBitmap() कहते हैं, अभी भी लिया छवि पूरी तरह से ओवरले पर अद्यतन किया जा रहा है।
  • यह एक और विकल्प है जो छवि को सहेजने के तुरंत बाद ओवरले के स्वचालित अपडेट करता है। मैं ईवेंट आधारित थ्रेड बना देता हूं और इसे EventWaitHandle का उपयोग करके बनाए गए अद्यतन ईवेंट की प्रतीक्षा करने के लिए बना देता हूं। Samplegrabber BufferCB फ़ंक्शन से लौटने से पहले, मैंने यह अद्यतन ईवेंट सेट किया था। जो बदले में प्रतीक्षा धागे के साथ आगे बढ़ता है। थ्रेड के अंदर मैं ShowHideBitmap फ़ंक्शन को कॉल करता हूं। इस परिदृश्य में, मुझे निम्नानुसार त्रुटि संदेश प्राप्त होता है।

Unable to case COM object of type 'DirectShowLib.VideoMixingRenderer9' to interface type 'DirectShowLib.IVMRMixerBitmap9'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{ced175e5-1935-4820-81bd-ff6ad00c9108}' failed due to the following error: No such interface supported (Exception from HRESULT: 0X80040002 (E_NOINTERFACE)

यहाँ यहाँ ShowHideBitmap समारोह के कोड ब्लॉक

//Declarations 
private static IBaseFilter vmr9 = null; 
private static IVMRMixerBitmap9 vmr9mixerBitmap = null; 
private IVMRWindowlessControl9 vmr9windowlessCtrl = null; 

private static void ShowHideBitmap(Boolean bEnable) 
{ 
int hr = 0; 
VMR9AlphaBitmap alphaBmp; 

if (!bEnable) 
{ 
    if (vmr9mixerBitmap != null) 
    { 
     // Get current Alpha Bitmap Parameters 
     hr = vmr9mixerBitmap.GetAlphaBitmapParameters(out alphaBmp); 
     DsError.ThrowExceptionForHR(hr); 

     // Disable them 
     alphaBmp.dwFlags = VMR9AlphaBitmapFlags.Disable; 

     // Update the Alpha Bitmap Parameters 
     hr = vmr9mixerBitmap.UpdateAlphaBitmapParameters(ref alphaBmp); 
     DsError.ThrowExceptionForHR(hr); 

     // Create a surface from our alpha bitmap 
     surface.Dispose(); 

     vmr9mixerBitmap = null; 

     //Release this alpha bitmap source. 
     if (alphaBitmap != null) 
     { 
      alphaBitmap.Dispose(); 
     } 
    } 
    return; 
} 
else 
{ 
    try 
    { 
     alphaBitmap = BitmapGenerator.GenerateAlphaBitmap(); 

     // Create a surface from our alpha bitmap 
     if(surface == null) 
      surface = new Surface(device, alphaBitmap, Pool.SystemMemory); 

     // Get the unmanaged pointer 
     unmanagedSurface = surface.GetObjectByValue(DxMagicNumber); 

     if (vmr9mixerBitmap == null) 
      vmr9mixerBitmap = (IVMRMixerBitmap9)vmr9; 


     // Set Alpha Bitmap Parameters for using a Direct3D surface 
     alphaBmp = new VMR9AlphaBitmap(); 
     alphaBmp.dwFlags = VMR9AlphaBitmapFlags.EntireDDS; 
     alphaBmp.pDDS = unmanagedSurface; 
     alphaBmp.rDest = GetDestRectangle(); 
     alphaBmp.fAlpha = 1.0f; 

     // Set Alpha Bitmap Parameters 
     hr = vmr9mixerBitmap.SetAlphaBitmap(ref alphaBmp); 
     DsError.ThrowExceptionForHR(hr); 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.Message); 
    } 
} 
} 

है और धागा अद्यतन घटना के लिए प्रतीक्षा करता है है।

Thread overlayupdatethreadhandle = new Thread(new ThreadStart(overlayupdatethread)); 
      overlayupdatethreadhandle.Start(); 

    private void overlayupdatethread() 
    { 
     do 
     { 
      overlayupdateeventhandle.WaitOne(); 
      ShowHideBitmap(GlobalVar.m_ShowOverlay); 
     } while (true); 
    } 

मैंने टाइमर का उपयोग करके इस ओवरले को अपडेट करने का प्रयास किया है जो पृष्ठभूमि में 100ms के अंतराल के साथ चल रहा था। टाइमर का उपयोग करना अच्छा काम कर रहा था, लेकिन इस ऑपरेशन के लिए, टाइमर का उपयोग करना बुरा विकल्प है। तो मैं थ्रेडिंग अवधारणा के साथ चले गए।

क्यों थ्रेड से कॉल करते समय इंटरफ़ेस विफल हो रहा है और मेनू विकल्पों से कॉल करते समय अच्छा काम करता है? क्या मुझे किसी विशेष चीज़ का ख्याल रखना चाहिए? मैंने parametrized धागा भी कोशिश की है, लेकिन कोई भाग्य नहीं है।

आपकी मदद के लिए अग्रिम धन्यवाद।

संपादित करें: यदि शोहेड बिटमैप को मुख्य थ्रेड से बुलाया जाता है, तो हर चीज ठीक काम करती है। यदि ShowHideBitmap को वर्कर थ्रेड से बुलाया जाता है, तो COM ऑब्जेक्ट अपवाद बनाता है।इस क्रॉस-थ्रेड ऑपरेशन को कैसे संभालें?

+0

+1। अच्छा प्रश्न। टिप्पणी के रूप में मैं पूरी तरह से सुनिश्चित नहीं हूं ... उम्मीद की क्रमबद्ध: अधिकांश COM वस्तुओं को एकल धागे से बुलाया जाने की उम्मीद है ... यदि आप इसे एकाधिक धागे से कॉल कर सकते हैं तो दस्तावेज स्पष्ट रूप से कॉल करेगा। (मुझे यह भी याद है कि ऑब्जेक्ट क्रॉस थ्रेड तक पहुंचने से पहले आपको अन्य थ्रेड पर COM प्रारंभ करना पड़ सकता है) ... –

+0

हाय एलेक्सी, हाँ आप सही हैं। मुख्य थ्रेड के अलावा एकाधिक थ्रेड से COM ऑब्जेक्ट को कॉल करना इस त्रुटि को बना रहा है। मैंने यह vmr9mixer बिटमैप इंटरफ़ेस प्रारंभ करने का भी प्रयास किया है मुख्य थ्रेड है और शोहाइड बिटमैप फ़ंक्शन (इस फ़ंक्शन में बनाने के बजाए) में इसका उपयोग कर रहा है, लेकिन परिणाम समान है। COM प्रारंभ करें, आपका मतलब है कि मुझे मुख्य थ्रेड में इंटरफ़ेस प्राप्त करना चाहिए और थ्रेड में एक ही इंटरफ़ेस का उपयोग करना चाहिए? क्या इस COM ऑब्जेक्ट को थ्रेड में एक्सेस किया जा रहा विस्तृत विवरण है? – Spark

+0

अंतर्निहित वीएमआर इंटरफेस थ्रेड के बीच भी COM नियमों का उल्लंघन कर सकते हैं। मूल कोड में हालांकि, प्रबंधित नहीं किया गया। सी # कॉम इंटरपॉप में यह इन गंदे चालों से अवगत नहीं है और मुझे लगता है कि यह एक समस्या हो सकती है: जब यह मार्शलिंग के माध्यम से इंटरफ़ेस को पार करने का प्रयास करता है, तो यह ऐसा करने में असमर्थ है, यह इंटरफेस खो देता है और आपके पास उन्हें उपलब्ध नहीं है कार्यकर्ता धागे पर। –

उत्तर

3

अपवाद रैटी है, COM में असामान्य नहीं है। इसका वास्तव में क्या अर्थ है "मुझे नहीं पता कि आपको एक इंटरफेस संदर्भ कैसे देना है जिसे आप एक कार्यकर्ता थ्रेड से उपयोग कर सकते हैं"। जो एक आम प्रकार की दुर्घटना है, इस प्रकार के COM घटक बिल्कुल थ्रेड-सुरक्षित नहीं हैं। और वे इसे लागू करते हुए लागू करते हैं, कार्यकर्ता थ्रेड से स्वचालित रूप से मालिक धागे में कॉल को मार्शल करते हैं। या आप उन्हें किसी अन्य थ्रेड से उपयोग करने की अनुमति नहीं दे रहे हैं क्योंकि मार्शलिंग व्यर्थ होगा, जिससे इसे बहुत धीमा कर दिया जा सकता है। वीएमआर बाद की श्रेणी में आता है।

यह .NET के विपरीत है, इसमें बहुत कक्षाएं हैं जो पूरी तरह से थ्रेड-असुरक्षित हैं। बुनियादी सामान भी, संग्रह कक्षाओं में से कोई भी उदाहरण के लिए नहीं हैं। लेकिन यह आपको इन कक्षाओं को थ्रेड में किसी भी तरह से उपयोग करने देता है, इसे थ्रेड-सुरक्षित बनाने के लिए इसे छोड़ देता है। उचित लॉकिंग का उपयोग करके यह अक्सर गलत हो जाता है, एक कौशल है।

COM हमेशा डिज़ाइन द्वारा थ्रेड-जागरूक रहा है। दर्शन के साथ कि थ्रेडिंग सही होने के लिए बहुत मुश्किल है, इसलिए इसे स्मार्ट लोगों की देखभाल करनी चाहिए। जो समय के 9 5% शानदार रूप से काम करता है। और आपको शेष समय में एक प्रमुख माइग्रेन देता है। जब एमएम थ्रेडिंग का ख्याल रखता है तो गरीब परफ का निदान करने के लिए कठिन द्वारा प्रेरित माइग्रेन की तरह। और क्रैपी त्रुटि रिपोर्टिंग जब यह नहीं करता है।

अच्छा, कोई भी नहीं कर सकता है, आपको वास्तव में उसी इंटरफ़ेस का उपयोग उसी थ्रेड से करना होगा जिसने वीएमआर इंस्टेंस बनाया है। उसके चारों ओर कोई रास्ता नहीं।

+0

हाय हंस, मैं बहुत परीक्षण के बाद वापस आ गया हूं। जैसा कि आपने निर्दिष्ट किया है, अब एप्लिकेशन किसी भी मुद्दे के साथ लगभग दो दिनों के लिए अच्छा काम करता है। मैंने कोड में कोई बदलाव नहीं किया है, मैंने इस तरह छोड़ा और अगले दिन परीक्षण किया। यह बिना किसी मुद्दे के अचानक अचानक काम किया।मैं इसके बारे में अधिक जानने के लिए इस मुद्दे को फिर से बनाने की कोशिश कर रहा हूं। जल्द ही आप पर वापस आ जाएगा। आपकी प्रभावी और मूल्यवान टिप्पणियों के लिए धन्यवाद :-) – Spark

1

डेल्फी लाइब्रेरी से श्रोता/ईवेंट हैंडलर ऑब्जेक्ट का उपयोग करने का प्रयास करते समय मुझे त्रुटि E_NOINTERFACE थी। मार्शलिंग & के साथ समस्या को दूर करने के लिए मैंने अलग-अलग धागे को प्रेषित किया है जो श्रोता को असाइन करता है और फिर घटनाओं को आग लगाने के लिए इसका उपयोग करता है।

इंटरफेस:

[ComVisible(true)] 
[Guid("2FFC2C20-A27B-4D67-AEA3-350223D3655F")] 
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
public interface IDataSystemInterfaceEventListener 
{ 
    void OnIntializeCompleted(int status); 
    void OnTerminateCompleted(int status); 
    void OnRunCompleted(int status); 
} 

[ComVisible(true)] 
[Guid("B9953413-A8C9-4CE2-9263-B488CA02E7EC")] 
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
public interface IDataSystemInterface 
{ 
    void Intialize(string config); 
    void StartRun(string conditions); 
    void StopRun(); 
    void Terminate();   

    IDataSystemInterfaceEventListener Listener { get; set; } 
} 

फिर कार्यान्वयन (नोटिस Dispatcher.CurrentDispatcher संग्रहीत)

[ComVisible(true)] 
[Guid("0818F830-DA37-4167-BF31-3A2C55A9BF2B")]   
public class DataSystemModule : IDataSystemInterface 
{ 
    private Dispatcher m_dispatcherListener = null; 
    private IDataSystemInterfaceEventListener m_listener = null; 
    public IDataSystemInterfaceEventListener Listener 
    { 
     get 
     { 
      return m_listener; 
     } 
     set 
     { 
      m_dispatcherListener = Dispatcher.CurrentDispatcher; 
      m_listener = value; 
     } 
    } 
} 
कोड में

तब:

if (Listener != null) 
{ 
    m_dispatcherListener.Invoke((Action)delegate() 
    { 
     Listener.OnTerminateCompleted((int)TerminateStatus.Completed); 
    }); 
} 

dispacther बिना श्रोता अलग सूत्र में कहा जाता है अगर यह त्रुटि उत्पन्न होगी

संबंधित मुद्दे