簡體   English   中英

COM 互操作在發布模式下失敗

[英]COM interop failing in release mode

我有一個控制台應用程序,它使用 ComImport 調用 windows 搜索。 雖然這在調試模式下工作正常......控制台應用程序在發布模式下崩潰。 可能是什么問題呢?

[ComImport]
    [Guid("9DAA54E8-CD95-4107-8E7F-BA3F24732D95")]
    [ClassInterface(ClassInterfaceType.None)]
    [TypeLibType(TypeLibTypeFlags.FCanCreate)]
    public class WordBreaker : IWordBreaker
    {
        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        public virtual extern bool Init([In] bool query, [In] uint maxTokenSize);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        public virtual extern void BreakText([In, MarshalAs(UnmanagedType.LPStruct)] TEXT_SOURCE textSource,
            [In] IWordSink wordSink, [In] IPhraseSink phraseSink);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        public virtual extern void ComposePhrase([In, MarshalAs(UnmanagedType.LPWStr)] string noun, [In] uint nounLen,
            [In, MarshalAs(UnmanagedType.LPWStr)] string modifier, [In] uint modifierLen,
            [In] uint attachmentType, [Out] out IntPtr phrase, [In, Out] ref uint phraseLen);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        public virtual extern IntPtr GetLicenseToUse();
    }

訪問 WordBreaker.BreakText function 時,代碼在發布模式下失敗。

它正在我的代碼中使用,如下所示

if (!string.IsNullOrWhiteSpace(text))
                try
                {
                    IWordBreaker breaker = new WordBreaker();
                    bool reqLicense = breaker.Init(query, 256);
                    if (reqLicense)
                    {
                        IntPtr lic = breaker.GetLicenseToUse();
                        string licText = Marshal.PtrToStringUni(lic);
                    }
                    TEXT_SOURCE source = new TEXT_SOURCE();
                    source.fillTextBuffer = FillTextBuffer;
                    source.buffer = text;
                    source.cur = 0;
                    source.end = (uint)(text.Length);
                    breaker.BreakText(source, new WordSink(result), null);
                }
                catch (Exception ex)
                {
                    Console.Out.WriteLine(ex.ToString());
                    //log4net.LogManager.GetLogger(typeof(WindowsIntegration)).Error("BreakText", ex);
                }
            var resultWithoutNoise = NoiseWord.Remove(result);
            return resultWithoutNoise;
        }

崩潰發生在breaker.BreakTextBreakText function 在應用程序崩潰之前被多次調用(500 到7000 次)。

故障轉儲說明以下異常信息The thread tried to read from or write to a virtual address for which it does not have the appropriate access. 注意:我沒有在我的代碼中使用任何線程。

這看起來像是垃圾收集器將文本移動到另一個位置的情況,因此記錄在 source.buffer 中的地址不再有效。 您沒有包含聲明 TEXT_SOURCE 的來源,因此我無法對此發表評論。 但是 BreakText 的聲明是不正確的。 MarshalAs(UnmanagedType.LPStruct) 不應該在那里使用。 UnmanagedType.LPStruct 僅在一種特定情況下受支持:將 System.Guid 值類型視為具有額外間接級別的非托管 GUID。 請參閱http://blogs.msdn.com/b/adam_nathan/archive/2003/04/23/56635.aspx如何將結構編組為指向結構的指針? .

該代碼至少需要一個線程,這就是錯誤所指的內容。 至於崩潰的類型,它本質上是訪問沖突,要么是 null 指針/對象引用(在本機代碼中),要么是緩沖區溢出。 檢查什么值。 細繩。 您在失敗時傳入的長度等。

如果您無法重現該問題並且它僅在發布時出現,我強烈建議您添加日志記錄以縮小您的問題范圍。

當您縮小問題范圍后,我會編輯您上面的帖子,以包含有關崩潰的更詳細信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM