성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] VT sequences to "CONOUT$" vs. STD_O...
[정성태] NetCoreDbg is a managed code debugg...
[정성태] Evaluating tail call elimination in...
[정성태] What’s new in System.Text.Json in ....
[정성태] What's new in .NET 9: Cryptography ...
[정성태] 아... 제시해 주신 "https://akrzemi1.wordp...
[정성태] 다시 질문을 정리할 필요가 있을 것 같습니다. 제가 본문에...
[이승준] 완전히 잘못 짚었습니다. 댓글 지우고 싶네요. 검색을 해보...
[정성태] 우선 답글 감사합니다. ^^ 그런데, 사실 저 예제는 (g...
[이승준] 수정이 안되어서... byteArray는 BYTE* 타입입니다...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>GetTickCount / GetTickCount64와 0x7FFE0000 주솟값</h1> <p> <a target='tab' href='https://www.sysnet.pe.kr/2/0/11063'>GetTickCount API</a>는 시스템이 시작된 이후 경과한 시간을 밀리초 단위로 반환합니다. (10ms ~ 16ms 단위입니다.)<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > GetTickCount function ; <a target='tab' href='https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-gettickcount'>https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-gettickcount</a> </pre> <br /> 위의 문서에도 나와있지만 이것의 반환값이 "DWORD"라서 32비트이므로 경과 시간을 표현하는데 한계가 있습니다. 대략 49.7일이 지나면 다시 0으로 돌아온다는 것이지요. 그래서 이 문제를 해결하려면 GetTickCount64를 쓰라고 권장하고 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > GetTickCount64 function ; <a target='tab' href='https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-gettickcount64'>https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-gettickcount64</a> </pre> <br /> 위의 문서에 추가된 덧글에 보면 (64비트까지 확장되었으므로) 기간이 "585 million years"까지 늘어나기 때문에 기간 걱정은 할 필요가 없어진 것입니다.<br /> <br /> 새삼스럽게 GetTickCount 이야기를 꺼낸 것은 재미있는 글을 보았기 때문입니다. ^^<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > GetTickCount를 대체할만한 방법 있을까요? ; <a target='tab' href='http://lab.gamecodi.com/board/zboard.php?id=GAMECODILAB_QnA_etc&no=3187&z='>http://lab.gamecodi.com/board/zboard.php?id=GAMECODILAB_QnA_etc&no=3187&z=</a> </pre> <br /> 위의 덧글 중에 보면 0x7FFE0000라는 주소에 32비트/64비트 윈도우 운영체제 공통으로 KSYSTEM_TIME이라는 구조체 값이 들어 있다는 것입니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > typedef struct _KSYSTEM_TIME { ULONG LowPart; LONG High1Time; LONG High2Time; } KSYSTEM_TIME, *PKSYSTEM_TIME; </pre> <br /> C#으로 이 값을 구해 보면 다음과 같이 코딩할 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > using System; using System.Runtime.InteropServices; class Program { static void Main(string[] args) { IntPtr ptr = new <span style='color: blue; font-weight: bold'>IntPtr(0x7FFE0008);</span> KSYSTEM_TIME systemTime = new KSYSTEM_TIME(); <span style='color: blue; font-weight: bold'>Marshal.PtrToStructure(ptr, systemTime);</span> Console.WriteLine("LowPart: " + systemTime.LowPart); Console.WriteLine("HighTime: " + systemTime.HighTime); Console.WriteLine("High2Time: " + systemTime.High2Time); ulong fullTime = (ulong)systemTime.LowPart | ((ulong)systemTime.HighTime << 32); Console.WriteLine("KSYSTEM_TIME: \t\t" + fullTime); /* 출력결과 LowPart: 2242934063 HighTime: 102 High2Time: 102 KSYSTEM_TIME: 441971822558 */ } } <span style='color: blue; font-weight: bold'>[StructLayout(LayoutKind.Sequential)] public class KSYSTEM_TIME { public uint LowPart; public int HighTime; public int High2Time; } </span> </pre> <br /> 재미있는 것은 GetTickCount/64 결과와의 비교값입니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Console.WriteLine("Environment.TickCount: \t" + Environment.TickCount); Console.WriteLine("GetTickCount: \t\t" + GetTickCount()); Console.WriteLine("GetTickCount64: \t" + GetTickCount64()); </pre> <br /> 위의 코드를 한꺼번에 실행시키면 다음과 같은 결과를 얻을 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > KSYSTEM_TIME: <span style='color: blue; font-weight: bold'>44283748</span>4163 Environment.TickCount: <span style='color: blue; font-weight: bold'>44283734</span> GetTickCount: <span style='color: blue; font-weight: bold'>44283750</span> GetTickCount64: <span style='color: blue; font-weight: bold'>44283750</span> </pre> <br /> Environment.TickCount는 내부적으로 GetTickCount를 부를 것이므로 값이 같아야 하지만 JIT 컴파일 시간으로 인해 약간 차이가 벌어지는 것 같습니다. JIT 컴파일로 인한 부작용을 없애기 위해 한번 컴파일된 상태로 호출하면 다음과 같이 마지막 3개의 값이 대개 동일하게 나옵니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > KSYSTEM_TIME: <span style='color: blue; font-weight: bold'>44283750</span>3715 Environment.TickCount: <span style='color: blue; font-weight: bold'>44283750</span> GetTickCount: <span style='color: blue; font-weight: bold'>44283750</span> GetTickCount64: <span style='color: blue; font-weight: bold'>44283750</span> </pre> <br /> 문제는 KSYSTEM_TIME값과 TickCount의 관계입니다. 위의 값을 보면 KSYSTEM_TIME 값에서 정밀도를 절삭한 유형이 TickCount로 해석되는 듯합니다. 즉, GetTickCount가 49.7일이 지나서 0부터 다시 시작한다면 KSYSTEM_TIME 역시 정밀도만 좋은 것일 뿐 49.7일에 대한 문제는 해결되지 않는 것으로 보입니다. (따라서, KSYSTEM_TIME 값이 GetTickCount에 대한 해결책으로 보이지는 않습니다.)<br /> <br /> 제가 해당 API를 설계한 사람이 아니어서 더 이상의 해석은 불가능하지만, 암튼 0x7FFE0000 이라는 특수한 주소를 알았다는 사실만으로 오늘은 만족해야겠습니다. ^^<br /> <br /> (<a target='tab' href='http://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=879&boardid=331301885'>첨부한 파일은 이 글의 예제 코드를 포함</a>합니다.)<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
9009
(왼쪽의 숫자를 입력해야 합니다.)