Сбой COM-взаимодействия в режиме выпуска - PullRequest
3 голосов
/ 29 июня 2011

У меня есть консольное приложение, которое выполняет поиск Windows с помощью ComImport. Хотя это нормально работает в режиме отладки ... консольное приложение падает в режиме выпуска. В чем может быть проблема?

[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.

Он используется в моем коде, как показано ниже

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.BreakText точно Функция BreakText вызывается много раз (от 500 до 7000 раз), прежде чем происходит сбой приложения.

В сообщении о сбое говорится об информации об исключении The thread tried to read from or write to a virtual address for which it does not have the appropriate access. примечание: я не использую никаких потоков в моем коде.

Ответы [ 3 ]

1 голос
/ 29 июня 2011

Коду нужен как минимум один поток, на который ссылается ошибка. Что касается типа сбоя, это, по сути, нарушение доступа, либо из-за нулевого указателя / ссылки на объект (в собственном коде), либо из-за переполнения буфера. Проверьте, какие значения. строка. длины и т. д., которые вы передаете в том месте, где он терпит неудачу.

1 голос
/ 10 сентября 2013

Это похоже на случай, когда сборщик мусора перемещает текст в другое место, поэтому адрес, записанный в 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 и Как маршалировать структуру как указатель на структуру? .

0 голосов
/ 29 июня 2011

Если вы не можете воспроизвести проблему и она делает это только в релизе, я настоятельно рекомендую вам добавить logging , чтобы сузить вашу проблему.

Когда вы сузилисьпо вашей проблеме я бы отредактировал ваш пост выше, чтобы включить более подробную информацию о сбое.

...