调用GetSystemTime / SetSystemTime时发生FatalExecutionEngineError

时间:2011-03-14 09:27:50

标签: .net winapi pinvoke fatal-error

我在应用程序中编写了一个小型工具,用于同步时间服务器的时间,该时间服务器使用Windows API函数GetSystemTimeSetSystemTime。一切正常,但现在每次拨打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 个答案:

答案 0 :(得分:1)

根据MSDN中的the signatures个函数,您应该使用的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);

您使用的是其他不同的东西吗?

答案 1 :(得分:1)

由于您将SYSTEMTIME定义为类,因此当您通过引用传递它时,实际上是将指针传递给指针,但是在非托管端,它期望指向SYSTEMTIME结构的指针。

将SYSTEMTIME的定义更改为结构,并按原样通过引用传递它。或者将其保留为课程并将声明更改为:

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

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

就个人而言,我会将其更改为结构。

相关问题