我在应用程序中编写了一个小型工具,用于同步时间服务器的时间,该时间服务器使用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.
答案 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);
就个人而言,我会将其更改为结构。