我想要做到这一简单的一块代码的工作。

#include <iostream>
#include <windows.h>


    void printSome (int i)
    {
        std::cout << i << std::endl;
    }

    void spawnThread (void (*threadName)(int i))
    {
        CreateThread 
            (
                0,      // default security attributes
                0,          // use default stack size 
                (LPTHREAD_START_ROUTINE)threadName,  // thread function name
                (LPVOID)i,          // argument to thread function 
                0,          // use default creation flags 
                0       // returns the thread identifier 
            );  
    }

    int main ()
    {
        spawnThread(printSome(155));
    }

我在窗户,使用与任何帮助,将极大地appriciated.

有帮助吗?

解决方案

就个人而言,我不会考虑传递函数指针,就像你试图像C ++一样。那是用C ++编写的C

相反,我会将这个东西包装在一个类中。最大的优势是你可以覆盖这个类,拥有你想要的许多成员,而不是每次都必须执行greazy cast技巧来获取你的参数。

代码有点啰嗦,所以我把它推到了最后。但它让你做的是这样的事情:

   class print_some : public basic_thread {
    private:
       int i;
    public:     
       print_some (int i) : i(i) {};
       action_callback () {
          std::cout << i << std::endl;
       }
    }
    int main () {
       print_some printer (155);
    }

以下是我们其中一个类中的一些示例代码:

class basic_thread : 
{
public:
   basic_thread();
protected:
   unsigned long m_ThreadId;

   virtual void action_callback () {};

   // Internal routine used to bridge between OS callback format and 
   // action_callback. *Must* be static for the OS.
   static unsigned long __stdcall self_calling_callback (void *parameter);
}

...和.cpp:

unsigned long __stdcall basic_thread::self_calling_callback (void *parameter) {
   if (parameter) {
      basic_thread * thread = reinterpret_cast<basic_thread *>(parameter);
      thread->action_callback();
   }
   return 0; // The value returned only matters if someone starts calling GetExitCodeThread
             // to retrieve it.
}

basic_thread::basic_thread () {
   // Start thread.
   m_Handle = CreateThread(NULL,
                           0,
                           self_calling_callback,
                           (PVOID)this,
                           0,
                           &m_ThreadId );
   if( !IsHandleValid() )
      throw StartException("CreateThread() failed", GetLastError());

}

其他提示

CreateThread需要2个参数:指向要作为线程执行的函数的指针,以及将给予线程的DWORD参数。你的spawnThread()函数只有1个参数(threadName);因为“i”,你认为它有2个args,但这实际上是“threadName”定义的一部分。类型。 (你也可以省略“i”;也就是说,你不需要将参数命名为“threadName”。)

无论如何,鉴于你需要2个参数,重新定义spawnThread:

   void spawnThread(void (*threadEntryPoint)(int), int argument)
   {
      CreateThread(0,0,
                   (LPTHREAD_START_ROUTINE)threadEntryPoint,
                   (LPVOID)argument,
                   0,0);
   }

注意我没有命名 threadEntryPoint的int参数;告诉编译器函数必须有一个int参数就足够了。

并称之为:

   spawnThread(printSome, 155);

无论如何,快速和肮脏,这将做你想要的。

第h

赖利。

你不能通过参数的信息在一个功能指针;它必须通过分开。这正是为什么CreateThread功能提供了一个void*参数可以指任何你想要的。

此外,你应该 使用_beginthread而不是CreateThread C++的应用。

最后,程序更有可能终止之前线没有运行。因此,你必须进入一个无限期的循环使用或使用API呼叫等待线完成。

以下是一个工作版本的使用 WaitForSingleObject 来块,直到线完成。

#include <iostream>
#include <process.h>
#include <windows.h>

void
printSome(int i)
{
    std::cout << i << std::endl;
}

HANDLE
spawnThread(void (*threadName)(int), int i)
{
    return (HANDLE) _beginthread((void (*)(void*)) threadName, 0, (LPVOID) i);      
}

int
main(int argc, char *argv[])
{
    HANDLE threadHandle;

    threadHandle = spawnThread(printSome, 155);
    WaitForSingleObject(threadHandle, INFINITE);

    return 0;
}

这里是一个更C++/面向对象的方式处理这一同样的情况:

#include <iostream>
#include <process.h>
#include <windows.h>

class Thread {
    static void proxy(void *arg) { (*(reinterpret_cast<Thread *> (arg)))(); }
    HANDLE thread_;

public:
    virtual ~Thread() {}
    virtual void operator()() = 0;  
    void start() { thread_ = (HANDLE) _beginthread(Thread::proxy, 0, this);}    
    void waitForExit() { WaitForSingleObject(thread_, INFINITE); }
};

class Printer : public Thread {
    int i_;

public:
    Printer(int i) : i_(i) {}
    void operator()() { std::cout << i_ << std::endl; }
};

int
main(int argc, char *argv[])
{
    Printer p(155);

    p.start();
    p.waitForExit();

    return 0;
}

如许多人已经提到的在这里,你可以不通过一种功能的指针和参数的应用在一个参数。

你的线

    spawnThread(printSome(155));

"应该"(在DWIM世界)的意思是"援引printSome在一个单独的线参数155".然而,它不是用C++理解它。C++看到"通过的结果printSome援引上155作为一个参数spawnThread".换句话说,该系列步骤:

  • 呼叫prinotSome与155作为论据。储存在临时储存器。
  • 呼叫spawnThread与内容的临时存储器作为其论据。

为了做到什么,你真的是说你有幽默C++和独立的参数,从功能。如何做到这一点是已经解释其他的答案。短是:

callOnOtherThreadWithArgument(功能、整数);

您可以在此处阅读以下操作: http://www.newty.de/ FPT / fpt.html

  

2.6如何将函数指针作为参数传递?

     

您可以将函数指针作为一个传递   函数的调用参数。你需要   例如,如果你想传递一个   指向回调函数的指针。该   以下代码显示了如何传递   指向返回一个函数的指针   int并获取一个float和两个char:

//------------------------------------------------------------------------------------
// 2.6 How to Pass a Function Pointer

// <pt2Func> is a pointer to a function which returns an int and takes a float and two char
void PassPtr(int (*pt2Func)(float, char, char))
{
   int result = (*pt2Func)(12, 'a', 'b');     // call using function pointer
   cout << result << endl;
}

// execute example code - 'DoIt' is a suitable function like defined above in 2.1-4
void Pass_A_Function_Pointer()
{
   cout << endl << "Executing 'Pass_A_Function_Pointer'" << endl;
   PassPtr(&DoIt);
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top