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

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 に答える
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 に答える