Serge Lidin создал достойную книгу по деталям MSIL: Опытная.NET 2.0 Ассемблера IL. Я также смог взять MSIL быстро путем рассмотрения простых методов с помощью Отражатель.NET и Ildasm (Учебное руководство) .
, понятия между MSIL и Байт-кодом Java очень похожи.
Я думаю, что стек был раздавлен из-за несоответствия соглашений о вызовах: попробуйте поместить атрибут
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
в объявление делегата обратного вызова.
Это не отвечает напрямую на ваш вопрос , но может привести к в правильном направлении в том, что касается режима отладки, а режим выпуска - нет:
Поскольку отладчик добавляет в стек много информации для ведения записей, обычно заполняя размер и расположение моей программы в памяти, я был «Повезло» в режиме отладки, набросав 912 байт памяти, которые не были очень важны. Однако без отладчика я писал поверх довольно важных вещей, в конечном итоге выходя за пределы своего собственного пространства памяти, в результате чего Interop удалял память, которой он не владел.
Каково определение DataLoggerWrap? Поле char может быть слишком маленьким для получаемых данных.
Я не уверен, чего вы пытаетесь достичь.
Несколько моментов:
1) Сборщик мусора более агрессивен в режиме выпуска, поэтому при плохом владении поведение, которое вы описываете, не является необычным.
2) Я не понимаю, что пытается сделать приведенный ниже код?
IntPtr ip2 = GCHandle.ToIntPtr(GCHandle.Alloc(new DataLoggerWrap(pData)));
DataLoggerWrap dlw = (DataLoggerWrap)GCHandle.FromIntPtr(ip2).Target;
Вы используете GCHandle.Alloc для блокировки экземпляр DataLoggerWrap в памяти, но тогда вы никогда не передаете его неуправляемому - так почему вы его блокируете? Вы также никогда не освобождаете его?
Вторая строка затем возвращает ссылку - почему круговой путь? почему ссылка - вы ее никогда не используете?
3) Вы устанавливаете для IntPtrs значение null - почему? - это не будет иметь никакого эффекта вне области действия функции.
4) Вам необходимо знать, каков контракт обратного вызова. Кому принадлежит pData, обратный вызов или вызывающая функция?
I'm with @jdehaan, except CallingConvetion.StdCall could be the answer, especially when the 3rd party lib is written in BC++, for example.