通过功能的指针在C++
-
03-07-2019 - |
题
我想要做到这一简单的一块代码的工作。
#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);
}