0

我在一个应用程序中编写了一个小工具,用于从时间服务器同步时间,它使用 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.
4

2 回答 2

1

根据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);

你用的是不同的东西吗?

于 2011-03-14T15:20:15.447 回答
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);

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

于 2011-03-16T17:35:22.310 回答