【问题标题】:C++ Class: Object that creates Thread + pointer to the function = Access violationC++ 类:创建线程的对象 + 指向函数的指针 = 访问冲突
【发布时间】:2011-09-20 18:51:23
【问题描述】:

我对我得到的奇怪异常感到非常惊讶。

class Threads { 
    public:
        Threads() {}
        ~Threads() {}
        void StartThread(int (*p)()); //pointer to a function 
    private: 
        HANDLE hThread; 
        DWORD dwThreadID; 
    }; 

方法 StartThread 应该接收指向我的函数的指针(它将在另一个线程中运行)。
这个功能很简单。 (如您所见,它位于类 Threads 之外):

int MyThread() 
{
return 0; 
}

这是创建线程的方法:

inline void Threads::StartThread(int (*p)()) 
{
    hThread = CreateThread(NULL, 
            0, 
            (LPTHREAD_START_ROUTINE)(*p)(), 
            NULL,  
            0, 
            &dwThreadID); 

   if (hThread == NULL) 
        {
            return;
        }
}

此处编译器出错:无法将参数 3 从“int”转换为“LPTHREAD_START_ROUTINE”。这就是我进行选角的原因。

在主函数中,我创建了 Threads 类型的对象,并尝试调用 StartThread 方法。作为参数,我发送指向函数 MyThread 的指针。

Threads *thread1; 
thread1 = new Threads(); 
thread1->StartThread(MyThread);

我认为 MyThread 必须从另一个线程开始。但是函数 MyTread 总是在主线程中运行!!!只有在 MyThread 结束后,另一个线程才会启动,然后我得到这个异常: ThreadClass.exe 中 0x00000000 处的未处理异常:0xC0000005:访问冲突。

我需要聪明的建议!

【问题讨论】:

标签: c++ multithreading winapi


【解决方案1】:

调用约定错误:

LPTHREAD_START_ROUTINE 是 __stdcall 方法而不是 __cdecl 方法,请参阅此处的文档:http://msdn.microsoft.com/en-us/library/aa964928.aspx

【讨论】:

    【解决方案2】:

    看起来你实际上是在调用这一行的函数...

    (LPTHREAD_START_ROUTINE)(*p)()
    

    ...它返回一个你正在投射的 int 。那是行不通的。怎么样:

    (LPTHREAD_START_ROUTINE)p 
    

    ...而不是?

    【讨论】:

    • @Girl_Developer:仅仅因为它看起来有效并不意味着它有效。函数签名完全错误——LPTHREAD_START_ROUTINE 采用LPVOID 类型的一个参数,返回DWORD,并使用__stdcall 调用约定。如果您的函数类型正确,则不需要也不应该使用强制转换。当你的线程例程返回时,它会因为调用约定错误而导致堆栈混乱而崩溃。
    • +1 以上亚当的评论;如果你在这里使用演员表,你可能做错了。我不认为在 Win32 中有任何情况下你应该需要转换一个函数。一般来说,演员应该被怀疑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-16
    • 1970-01-01
    • 2012-10-12
    • 2013-03-07
    相关资源
    最近更新 更多