我建立了一个Win32 Application程序,前面包含了process.h
但编译hThreadHandle = (HANDLE) _beginthread(RenderingThreadEntryPoint,0,NULL);
提示_beginthread()未定义。请问何故。
但编译hThreadHandle = (HANDLE) _beginthread(RenderingThreadEntryPoint,0,NULL);
提示_beginthread()未定义。请问何故。
#include <windows.h>
#include <process.h>
#include <stdio.h>
#include <math.h>
#include <gl\gl.h>
#include <gl\glu.h>
#include "com.h"
HDC hDC = NULL; // Private GDI Device context
HWND hMainWindow = NULL;// Main Application Window
LARGE_INTEGER timerFrequency; // High resolution timer frequency
static LARGE_INTEGER startTime; // Time at start of simulationCRITICAL_SECTION csThreadSafe; // Critical section
struct RENDER_STATE rsRenderData; // Communication between threadsLRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{ static HANDLE hThreadHandle = NULL; // Thread Handle
static int nLastFrames = 0; // Frame count on last read
//处理感兴趣的消息
switch (message)
{
case WM_CREATE:
hDC = GetDC(hwnd); // Initialize the critical section
InitializeCriticalSection(&csThreadSafe);
// Initialize interthread communication
rsRenderData.uiFrames = 0;
rsRenderData.bResize = FALSE;
rsRenderData.bTerminate = FALSE;
rsRenderData.bFatalError = FALSE;
rsRenderData.bModifyFlag = TRUE; QueryPerformanceFrequency(&timerFrequency);
QueryPerformanceCounter(&startTime); // Create the rendering thread
hThreadHandle = (HANDLE) _beginthread(RenderingThreadEntryPoint,0,NULL); // This timer will be used to recalculate the frame rate every five seconds
SetTimer(hwnd, 1, 5000, NULL); // Every Five Seconds
break; case WM_DESTROY:
//当用户关闭窗口,窗口销毁,程序需结束,发退出消息,以退出消息循环
PostQuitMessage (0) ;
return 0 ;
}
//其他消息交给由系统提供的缺省处理函数
return ::DefWindowProc (hwnd, message, wParam, lParam) ;
}int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPtrIns,LPSTR lpCmdLine,int nShowCmd)
{
static TCHAR szAppName[] = TEXT ("HelloWin") ; //窗口类名称
//定制"窗口类"结构
WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ; //关联消息处理函数
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ; //实例句柄
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; //图标
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; //光标
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); //画刷
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName; //类名称
if(!RegisterClass(&wndclass))
{
MessageBeep(0);
};
HWND hwnd ;
hwnd = CreateWindow (szAppName, //窗口类名称
TEXT ("The Hello Program"), //窗口标题
WS_OVERLAPPEDWINDOW, //窗口风格
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance, //实例句柄
NULL);
ShowWindow(hwnd,nShowCmd);
UpdateWindow(hwnd); MSG msg ; while (GetMessage (&msg, NULL, 0, 0)) //从消息队列中取消息
{
TranslateMessage (&msg) ; //转换消息
DispatchMessage (&msg) ; //派发消息
}
return msg.wParam ;}
建议使用_beginthreadex函数来启动线程
#ifndef _MT
#define _MT
#endif#ifndef MT
#define MT
#endif
2. 头文件顺序没错
3. sevencat(七猫)is right.think you!
4. 谢谢大家参与。
uintptr_t __cdecl _beginthreadex (
void *security,
unsigned stacksize,
unsigned (__stdcall * initialcode) (void *),
void * argument,
unsigned createflag,
unsigned *thrdaddr
)
{
_ptiddata ptd; /* pointer to per-thread data */
uintptr_t thdl; /* thread handle */
unsigned long errcode = 0L; /* Return from GetLastError() */
unsigned dummyid; /* dummy returned thread ID */ if ( initialcode == NULL ) {
errno = EINVAL;
return( (uintptr_t)0 );
} /*
* Allocate and initialize a per-thread data structure for the to-
* be-created thread.
*/
if ( (ptd = _calloc_crt(1, sizeof(struct _tiddata))) == NULL )
goto error_return; /*
* Initialize the per-thread data
*/ _initptd(ptd); ptd->_initaddr = (void *) initialcode;
ptd->_initarg = argument;
ptd->_thandle = (uintptr_t)(-1); /*
* Make sure non-NULL thrdaddr is passed to CreateThread
*/
if ( thrdaddr == NULL )
thrdaddr = &dummyid; /*
* Create the new thread using the parameters supplied by the caller.
*/
if ( (thdl = (uintptr_t)
CreateThread( security,
stacksize,
_threadstartex,
(LPVOID)ptd,
createflag,
thrdaddr))
== (uintptr_t)0 )
{
errcode = GetLastError();
goto error_return;
} /*
* Good return
*/
return(thdl); /*
* Error return
*/
error_return:
/*
* Either ptd is NULL, or it points to the no-longer-necessary block
* calloc-ed for the _tiddata struct which should now be freed up.
*/
_free_crt(ptd); /*
* Map the error, if necessary.
*
* Note: this routine returns 0 for failure, just like the Win32
* API CreateThread, but _beginthread() returns -1 for failure.
*/
if ( errcode != 0L )
_dosmaperr(errcode); return( (uintptr_t)0 );
}uintptr_t __cdecl _beginthread (
void (__cdecl * initialcode) (void *),
unsigned stacksize,
void * argument
)
{
_ptiddata ptd; /* pointer to per-thread data */
uintptr_t thdl; /* thread handle */
unsigned long errcode = 0L; /* Return from GetLastError() */ if ( initialcode == NULL ) {
errno = EINVAL;
return( (uintptr_t)(-1) );
} /*
* Allocate and initialize a per-thread data structure for the to-
* be-created thread.
*/
if ( (ptd = _calloc_crt(1, sizeof(struct _tiddata))) == NULL )
goto error_return; /*
* Initialize the per-thread data
*/ _initptd(ptd); ptd->_initaddr = (void *) initialcode;
ptd->_initarg = argument; /*
* Create the new thread. Bring it up in a suspended state so that
* the _thandle and _tid fields are filled in before execution
* starts.
*/
if ( (ptd->_thandle = thdl = (uintptr_t)
CreateThread( NULL,
stacksize,
_threadstart,
(LPVOID)ptd,
CREATE_SUSPENDED,
(LPDWORD)&(ptd->_tid) ))
== (uintptr_t)0 )
{
errcode = GetLastError();
goto error_return;
} /*
* Start the new thread executing
*/
if ( ResumeThread( (HANDLE)thdl ) == (DWORD)(-1) ) {
errcode = GetLastError();
goto error_return;
} /*
* Good return
*/
return(thdl); /*
* Error return
*/
error_return:
/*
* Either ptd is NULL, or it points to the no-longer-necessary block
* calloc-ed for the _tiddata struct which should now be freed up.
*/
_free_crt(ptd); /*
* Map the error, if necessary.
*/
if ( errcode != 0L )
_dosmaperr(errcode); return( (uintptr_t)(-1) );
}
void __cdecl _endthread (
void
)
{
_ptiddata ptd; /* pointer to thread's _tiddata struct */ /*
* Call fp termination, if necessary
*/
if ( _FPmtterm != NULL )
(*_FPmtterm)(); if ( (ptd = _getptd()) == NULL )
_amsg_exit(_RT_THREAD); /*
* Close the thread handle (if there was one)
*/
if ( ptd->_thandle != (uintptr_t)(-1) )
(void) CloseHandle( (HANDLE)(ptd->_thandle) );
//看出了吧?多了这一行。这个句柄不用再显式Close了。 /*
* Free up the _tiddata structure & its subordinate buffers
* _freeptd() will also clear the value for this thread
* of the FLS variable __tlsindex.
*/
_freeptd(ptd); /*
* Terminate the thread
*/
ExitThread(0);}void __cdecl _endthreadex (
unsigned retcode
)
{
_ptiddata ptd; /* pointer to thread's _tiddata struct */ /*
* Call fp termination, if necessary
*/
if ( _FPmtterm != NULL )
(*_FPmtterm)(); if ( (ptd = _getptd()) == NULL )
_amsg_exit(_RT_THREAD); /*
* Free up the _tiddata structure & its subordinate buffers
* _freeptd() will also clear the value for this thread
* of the FLS variable __tlsindex.
*/
_freeptd(ptd); /*
* Terminate the thread
*/
ExitThread(retcode);}