在dll中写线程时要特别注意什么吗,我调用导出函数后在执行到CreateThread()时应用程序就发生错误了,不知道问题出在哪了,求助

解决方案 »

  1.   

    按理说是不会出错的,应该是你的调用有问题,比如说线城函数类型没有定义好,或者参数传输错误,不过启动线城最好使用_beginthread。而不要直接使用CreateThread,
      

  2.   

    没用过你说那个_beginthread啊,也找不到这个函数的定义,简单说一下通常的用法
      

  3.   

    FROM MSDN_beginthread, _beginthreadex
    Create a thread.unsigned long _beginthread( void( __cdecl *start_address )( void * ), unsigned stack_size, void *arglist );unsigned long _beginthreadex( void *security, unsigned stack_size, unsigned ( __stdcall *start_address )( void * ), void *arglist, unsigned initflag, unsigned *thrdaddr );Routine Required Header Compatibility 
    _beginthread <process.h> Win 95, Win NT   
    _beginthreadex <process.h> Win 95, Win NT   
    For additional compatibility information, see Compatibility in the Introduction.LibrariesLIBCMT.LIB Multithread static library, retail version 
    MSVCRT.LIB Import library for MSVCRT.DLL, retail version 
    To use _beginthread or _beginthreadex, the application must link with one of the multithreaded C run-time libraries.Return ValueIf successful, each of these functions returns a handle to the newly created thread. _beginthread returns –1 on an error, in which case errno is set to EAGAIN if there are too many threads, or to EINVAL if the argument is invalid or the stack size is incorrect. _beginthreadex returns 0 on an error, in which case errno and doserrno are set.Parametersstart_addressStart address of routine that begins execution of new threadstack_sizeStack size for new thread or 0arglistArgument list to be passed to new thread or NULLsecuritySecurity descriptor for new thread; must be NULL for Windows 95 applicationsinitflagInitial state of new thread (0 for running or CREATE_SUSPEND for suspended)thrdaddrPoints to a 32-bit variable that receives the thread identifierResThe _beginthread function creates a thread that begins execution of a routine at start_address. The routine at start_address must use the __cdecl calling convention and should have no return value. When the thread returns from that routine, it is terminated automatically._beginthreadex resembles the Win32CreateThread API more closely than does _beginthread. _beginthreadex differs from _beginthread in the following ways: _beginthreadex has three additional parameters: initflag, security, threadaddr. The new thread can be created in a suspended state, with a specified security (Windows NT only), and can be accessed using thrdaddr, which is the thread identifier.
    The routine at start_address passed to _beginthreadex must use the __stdcall calling convention and must return a thread exit code.
    _beginthreadex returns 0 on failure, rather than –1.
    A thread created with _beginthreadex is terminated by a call to _endthreadex. 
    You can call _endthread or _endthreadex explicitly to terminate a thread; however, _endthread or _endthreadex is called automatically when the thread returns from the routine passed as a parameter. Terminating a thread with a call to endthread or _endthreadex helps to ensure proper recovery of resources allocated for the thread._endthread automatically closes the thread handle (whereas _endthreadex does not). Therefore, when using _beginthread and _endthread, do not explicitly close the thread handle by calling the Win32CloseHandle API. This behavior differs from the Win32ExitThread API.Note   For an executable file linked with LIBCMT.LIB, do not call the Win32 ExitThread API; this prevents the run-time system from reclaiming allocated resources. _endthread and _endthreadex reclaim allocated thread resources and then call ExitThread.The operating system handles the allocation of the stack when either _beginthread or _beginthreadex is called; you do not need to pass the address of the thread stack to either of these functions. In addition, the stack_size argument can be 0, in which case the operating system uses the same value as the stack specified for the main thread.arglist is a parameter to be passed to the newly created thread. Typically it is the address of a data item, such as a character string. arglist may be NULL if it is not needed, but _beginthread and _beginthreadex must be provided with some value to pass to the new thread. All threads are terminated if any thread calls abort, exit, _exit, or ExitProcess.Example/* BEGTHRD.C illustrates multiple threads using functions:
     *
     *      _beginthread            _endthread
     *
     *
     * This program requires the multithreaded library. For example,
     * compile with the following command line:
     *     CL /MT /D "_X86_" BEGTHRD.C
     *
     * If you are using the Visual C++ development environment, select the 
     * Multi-Threaded runtime library in the compiler Project Settings 
     * dialog box.
     * 
     */#include <windows.h>
    #include <process.h>    /* _beginthread, _endthread */
    #include <stddef.h>
    #include <stdlib.h>
    #include <conio.h>void Bounce( void *ch );
    void CheckKey( void *dummy );/* GetRandom returns a random integer between min and max. */
    #define GetRandom( min, max ) ((rand() % (int)(((max) + 1) - (min))) + (min))BOOL repeat = TRUE;     /* Global repeat flag and video variable */
    HANDLE hStdOut;         /* Handle for console window */
    CONSOLE_SCREEN_BUFFER_INFO csbi;    /* Console information structure */void main()
    {
        CHAR    ch = 'A';    hStdOut = GetStdHandle( STD_OUTPUT_HANDLE );    /* Get display screen's text row and column information. */
       GetConsoleScreenBufferInfo( hStdOut, &csbi );    /* Launch CheckKey thread to check for terminating keystroke. */
        _beginthread( CheckKey, 0, NULL );    /* Loop until CheckKey terminates program. */
        while( repeat )
        {
            /* On first loops, launch character threads. */
            _beginthread( Bounce, 0, (void *) (ch++)  );        /* Wait one second between loops. */
            Sleep( 1000L );
        }
    }/* CheckKey - Thread to wait for a keystroke, then clear repeat flag. */
    void CheckKey( void *dummy )
    {
        _getch();
        repeat = 0;    /* _endthread implied */}/* Bounce - Thread to create and and control a colored letter that moves
     * around on the screen.
     *
     * Params: ch - the letter to be moved
     */
    void Bounce( void *ch )
    {
        /* Generate letter and color attribute from thread argument. */
        char    blankcell = 0x20;
        char    blockcell = (char) ch;
        BOOL    first = TRUE;
       COORD   oldcoord, newcoord;
       DWORD   result;
        /* Seed random number generator and get initial location. */
        srand( _threadid );
        newcoord.X = GetRandom( 0, csbi.dwSize.X - 1 );
        newcoord.Y = GetRandom( 0, csbi.dwSize.Y - 1 );
        while( repeat )
        {
            /* Pause between loops. */
            Sleep( 100L );        /* Blank out our old position on the screen, and draw new letter. */
            if( first )
                first = FALSE;
            else
             WriteConsoleOutputCharacter( hStdOut, &blankcell, 1, oldcoord, &result );
             WriteConsoleOutputCharacter( hStdOut, &blockcell, 1, newcoord, &result );        /* Increment the coordinate for next placement of the block. */
            oldcoord.X = newcoord.X;
            oldcoord.Y = newcoord.Y;
            newcoord.X += GetRandom( -1, 1 );
            newcoord.Y += GetRandom( -1, 1 );        /* Correct placement (and beep) if about to go off the screen. */
            if( newcoord.X < 0 )
                newcoord.X = 1;
            else if( newcoord.X == csbi.dwSize.X )
                newcoord.X = csbi.dwSize.X - 2;
            else if( newcoord.Y < 0 )
                newcoord.Y = 1;
            else if( newcoord.Y == csbi.dwSize.Y )
                newcoord.Y = csbi.dwSize.Y - 2;        /* If not at a screen border, continue, otherwise beep. */
            else
                continue;
            Beep( ((char) ch - 'A') * 100, 175 );
        }
        /* _endthread given to terminate */
        _endthread();
    }
      

  4.   

    楼上的我试过了,一运行程序还是错误结束了,我现在可以进入导出dll函数里,然后在调用开始进程时就出现了错误,是不是线程函数有什么特殊的说明啊?
      

  5.   

    在MSDN上看过,忘记了,你再查下MSDN看,在DLL中如果使用线程.线程函数必须是全局的,不知道有什么冲突没.呵.
      

  6.   

    CWinThread* pThread;
    pThread = AfxBeginThread(ThreadProc, NULL) ;
      

  7.   

    HANDLE pThread;
    pThread=CreateThread(NULL,0,ThreadProc,(LPVOID)NULL,0,&dwThreadID);