在C ++中传递函数指针

我想做这个简单的代码工作。

#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)); } 

我在窗户上,使用vs任何帮助将大大appriciated。

Solutions Collecting From Web of "在C ++中传递函数指针"

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

相反,我会把这个东西包装在课堂上。 最大的好处是你可以重写这个类,然后有很多你想要的成员,而不是每次都必须执行灰色的铸造技巧来获取你的参数。

代码有点冗长,所以我把它推到了最后。 但是它可以让你做的是这样的:

  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); } 

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

 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); 你认为它有2个参数,因为“我”,但这实际上是“threadName”类型的定义的一部分。 (你也可以省略“我”;也就是说,你不需要把参数命名为“threadName”)。

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

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

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

并称之为:

  spawnThread(printSome, 155); 

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

心连心。

赖利。

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

此外,您应该使用_beginthread而不是CreateThread for 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世界中)意思是“在具有参数155的单独线程上调用printSome”。 但是,C ++并不是这样理解的。 C ++看到“把printSome的结果作为一个参数传递给spawnThread”。 换句话说,步骤的顺序是:

  • 调用与155作为参数的prinotSome。 将其存储在临时内存中。
  • 以临时内存的内容作为参数调用spawnThread。

为了做你真正的意思,你必须幽默C ++和功能分开的论点。 如何做到这一点已经在其他答案解释。 它的缺点是:

callOnOtherThreadWithArgument(function,integer);

你可以阅读你如何做到这一点: 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); }