[英]Passing function Pointers in 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));
}
我在Windows上,使用vs.任何帮助将非常适合。
CreateThread需要2个参数:指向要作为线程执行的函数的指针,以及将给予线程的DWORD参数。 你的spawnThread()函数只有1个参数(threadName); 你认为它有2个args因为“i”,但这实际上是“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);
无论如何,快速和肮脏,这将做你想要的。
心连心。
赖利。
就个人而言,我不会考虑传递函数指针,就像你试图像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函数提供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));
“should”(在DWIM世界中)表示“在带有参数155的单独线程上调用printSome”。 但是,并不是C ++如何理解它。 C ++看到“将在155上调用的printSome的结果作为参数传递给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);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.