下記から。
https://blogs.msdn.microsoft.com/oldnewthing/20041025-00/?p=37483
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase)https://msdn.microsoft.com/ja-jp/library/x98tx3cf.aspx
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
...
void main()
{
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
...
}下記から。
https://blogs.msdn.microsoft.com/oldnewthing/20061103-07/?p=29133
constexpr BOOL WIN32_FROM_HRESULT(HRESULT hr, OUT DWORD *pdwWin32) noexcept
{
if ((hr & 0xFFFF0000) == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, 0)) {
*pdwWin32 = HRESULT_CODE(hr);
return TRUE;
}
else if (hr == S_OK) {
*pdwWin32 = HRESULT_CODE(hr);
return TRUE;
}
return FALSE;
}
constexpr DWORD WIN32_FROM_HRESULT(HRESULT hr) noexcept
{
DWORD dwError = 65535;
WIN32_FROM_HRESULT(hr, &dwError);
return dwError;
}| from \ to | HRESULT | Win32 | NTSTATUS |
|---|---|---|---|
| HRESULT | - | WIN32_FROM_HRESULT | N/A |
| Win32 | HRESULT_FROM_WIN32 function _Translates_Win32_to_HRESULT_ inline function __HRESULT_FROM_WIN32 macro |
- | N/A |
| NTSTATUS | HRESULT_FROM_NT | RtlNtStatusToDosError | - |
https://msdn.microsoft.com/ja-jp/library/yhfk0thd.aspx
__declspec( property( get=get_func_name ) ) declarator
__declspec( property( put=put_func_name ) ) declarator
__declspec( property( get=get_func_name, put=put_func_name ) ) declarator ちなみにdeclarator では、decltype(get_foo()) foo; のようにメンバー関数の戻り値を型に使用できないので、メンバー毎に型を指定する必要がある。
それっぽいソース。
void MyGetSystemTimePreciseAsFileTime(LPFILETIME lpSystemTimeAsFileTime)
{
union filetymeunion
{
FILETIME ft;
LONG64 QuadPart;
};
static volatile LONG firsttime = 0;
static LARGE_INTEGER Frequency = { 0 };
static CRITICAL_SECTION cs;
static LARGE_INTEGER lastTick;
static filetymeunion lastTime = { 0 };
filetymeunion now;
if (InterlockedCompareExchange(&firsttime, 1, 0) == 0)
{
QueryPerformanceFrequency(&Frequency);
InitializeCriticalSection(&cs);
firsttime = 2;
}
while (firsttime != 2)
{
// nop
}
GetSystemTimeAsFileTime(&now.ft);
EnterCriticalSection(&cs);
if (lastTime.QuadPart == now.QuadPart)
{
// same time
LARGE_INTEGER currentTick;
QueryPerformanceCounter(¤tTick);
LONGLONG diff = currentTick.QuadPart - lastTick.QuadPart;
diff *= 10000000; // 100 nano second
diff /= Frequency.QuadPart;
now.QuadPart += diff;
}
else
{
QueryPerformanceCounter(&lastTick);
}
LeaveCriticalSection(&cs);
*lpSystemTimeAsFileTime = now.ft;
}それっぽいソース
//#if (_WIN32_WINNT < 0x0502)
static DWORD
WINAPI
GetThreadId(
_In_ HANDLE Thread
)
{
typedef struct _THREAD_BASIC_INFORMATION {
NTSTATUS ExitStatus;
PVOID TebBaseAddress;
CLIENT_ID ClientId;
KAFFINITY AffinityMask;
KPRIORITY Priority;
KPRIORITY BasePriority;
} THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;
THREADINFOCLASS ThreadBasicInformation = static_cast<THREADINFOCLASS>(0);
ULONG ReturnLength;
THREAD_BASIC_INFORMATION info;
typedef NTSTATUS
(NTAPI *NtQueryInformationThread) (
IN HANDLE ThreadHandle,
IN THREADINFOCLASS ThreadInformationClass,
OUT PVOID ThreadInformation,
IN ULONG ThreadInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
NtQueryInformationThread fp = (NtQueryInformationThread)::GetProcAddress(::LoadLibraryA("Ntdll.dll"), "NtQueryObject");
NTSTATUS status = fp(Thread, ThreadBasicInformation, &info, sizeof(info), NULL);
if (NT_SUCCESS(status))
return reinterpret_cast<DWORD>(info.ClientId.UniqueThread);
else
{
typedef ULONG
(NTAPI *RtlNtStatusToDosError) (
NTSTATUS Status
);
RtlNtStatusToDosError fp = (RtlNtStatusToDosError)::GetProcAddress(::LoadLibraryA("Ntdll.dll"), "RtlNtStatusToDosError");
::SetLastError(fp(status));
return 0;
}
}
//#endif // _WIN32_WINNT >= 0x0502https://msdn.microsoft.com/en-us/library/windows/desktop/ms686360(v=vs.85).aspx
スレッドにAPC関数を紐づけて(APCキュー)、特定の関数(SleepEx, SignalObjectAndWait, WaitForSingleObjectEx, WaitForMultipleObjectsEx, or MsgWaitForMultipleObjectsEx)の引数でalertableを指定した場合に、APC関数がコールバックされる。
以下の理由により、非常に使いづらい。
- APC関数明示的なトリガーを必要とする。
- APC関数が実行している間は、呼び出し元に復帰しない。
SleepExで指定したミリ秒よりAPC関数の実行に時間がかかっても、APC関数が中断されることはない。 ExitThreadまたはTerminateThreadでスレッドを終了するとAPC関数は呼び出されない。
DLLに特定のセクションを用意することで、ロードするEXE間で共有メモリ扱いすることができる
#pragma comment(linker, "/section:.shared,rws")
#pragma data_seg(".shared")
SomeClass g_value = SomeClass();
#pragma data_seg()