FatalExecutionEngineError при вызове GetSystemTime / SetSystemTime - PullRequest
0 голосов
/ 14 марта 2011

Я написал небольшую утилиту в приложении, которое синхронизирует время с сервером времени, который использует функции Windows API GetSystemTime и SetSystemTime. Все работало нормально, но теперь каждый раз, когда я звоню Get/SetSystemTime, я получаю сообщение об ошибке:

FatalExecutionEngineError was detected  
Message:  
The runtime has encountered a fatal error.  
The address of the error was at 0x792bee10, on thread 0x48c.  
The error code is 0xc0000005. This error may be a bug in the CLR  
or in the unsafe or non-verifiable portions of user code.  
Common sources of this bug include user marshaling errors for COM-interop
or PInvoke, which may corrupt the stack.

Теперь, поскольку единственный небезопасный код - это вызов функций Win32 (это даже небезопасно ??), кажется, это не может быть в моем коде - это и я ничего не изменил, так как он фактически работал ...

Есть идеи, что здесь может происходить?

Вызовы Win32 выполняются с использованием:

public class SystemTime
        {
            public ushort Year;
            public ushort Month;
            public ushort DayOfWeek;
            public ushort Day;
            public ushort Hour;
            public ushort Minute;
            public ushort Second;
            public ushort Millisecond;

            public static implicit operator SystemTime(DateTime dt)
            {
                SystemTime rval = new SystemTime();
                rval.Year = (ushort)dt.Year;
                rval.Month = (ushort)dt.Month;
                rval.Day = (ushort)dt.Day;
                rval.DayOfWeek = (ushort)dt.DayOfWeek;
                rval.Hour = (ushort)dt.Hour;
                rval.Minute = (ushort)dt.Minute;
                rval.Second = (ushort)dt.Second;
                rval.Millisecond = (ushort)dt.Millisecond;
                return rval;
            }

            public static implicit operator DateTime(SystemTime st)
            {
                return new DateTime(st.Year, st.Month, st.Day, st.Hour, st.Minute, st.Second, st.Millisecond);
            }
        }; 

        [DllImport("kernel32.dll", EntryPoint = "GetSystemTime")]
        public extern static void Win32GetSystemTime(ref SystemTime sysTime); 
        [DllImport("kernel32.dll", EntryPoint = "SetSystemTime")]
        public extern static bool Win32SetSystemTime(ref SystemTime sysTime);

РЕДАКТИРОВАТЬ: Теперь тот же код (без изменений) дает мне AccessViolation ???

Attempted to read or write protected memory.  
This is often an indication that other memory is corrupt.

Ответы [ 2 ]

1 голос
/ 16 марта 2011

Поскольку вы определяете SYSTEMTIME как класс, когда вы передаете его по ссылке, вы фактически передаете указатель на указатель, но на неуправляемой стороне он ожидает указатель на структуру SYSTEMTIME.

Любое изменениеваше определение SYSTEMTIME для структуры и передать его по ссылке, как вы делаете сейчас.Или оставьте его как класс и измените ваши объявления на:

[DllImport("kernel32.dll")]
static extern void GetSystemTime([Out] SYSTEMTIME systemTime);

[DllImport("kernel32.dll")]
public extern static uint SetSystemTime([In] SYSTEMTIME systemTime);

Лично я бы изменил его на структуру.

1 голос
/ 14 марта 2011

Исходя из сигнатур функций из MSDN, вы должны использовать следующие сигнатуры PInvoke:

[StructLayout(LayoutKind.Sequential)]
public class SYSTEMTIME
{
   public ushort Year;
   public ushort Month;
   public ushort DayOfWeek;
   public ushort Day;
   public ushort Hour;
   public ushort Minute;
   public ushort Second;
   public ushort Milliseconds;
}

[DllImport("kernel32.dll")]
static extern void GetSystemTime(out SYSTEMTIME systemTime);

[DllImport("kernel32.dll")]
public extern static uint SetSystemTime(ref SYSTEMTIME systemTime);

Вы используете что-то другое?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...