gpt4 book ai didi

c++ - 从方法指针动态创建通用函数指针,推导返回值和参数

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:56:44 25 4
gpt4 key购买 nike

我有这个帮助器类,我用它来为需要静态 C 函数的代码调用成员方法。这个特定的“版本”与 Windows LPTHREADROUTINE 回调兼容,采用 DWORD (class::method) (void *) 函数作为参数,调用如下:

CreateThread(NULL, 0, runThreadFunction<SomeClass>, makeThreadInfo(&myClass, &SomeClass::ThreadFunction, NULL), 0, NULL);

我希望让整个事情变得通用,我知道这可以用新的 C++11 标准来完成,但我无法实现。

#pragma once
#include <stdafx.h>

template <typename C>
struct ThreadInfo
{
// we have an object
C* obj;
// and that object has a function that takes void* and returns DWORD, and so is suitable for a threadproc (except for it being a member function)

DWORD (C::* function)(void*);
// and we have any amount of extra data that we might need.

void* data;
// default copy c-tor, d-tor and operator= are fine

ThreadInfo(C* o, DWORD (C::*func)(void*), void* d) : obj(o), function(func), data(d)
{
}
};

template <typename C>
DWORD WINAPI RunThreadFunction(void* data)
{
shared_ptr<ThreadInfo<C> > ti((ThreadInfo<C>*)data);
//ThreadInfo<C>* ti = (ThreadInfo<C>*) data;
return ((ti->obj)->*(ti->function))(ti->data);
}

template <typename C>
void* MakeThreadInfo(C* o, DWORD (C::* f)(void*), void* d)
{
return (void*)new ThreadInfo<C>(o, f, d);
}

我试过将 MakeThreadInfo 函数的接口(interface)更改为如下所示:

template <typename C, typename R, typename... P>
void* MakeThreadInfo(C* o, std::function<R(P&...)> f, void* d)

这似乎是可行的方法,但我无法将此值向上游传递。


这是我想要得到的:

给定一个带有方法 MyMethod 的 MyClass 类,以及一个变量 返回类型的回调和一个或多个不同类型 的参数(最后一个是 void *userData),我如何在尽可能少的样板化的情况下将东西传递给回调并让它依次调用 MyClass::MyMethod。

举例说明:

typedef bool (*Callback1)(void *userData);
typedef int (*Callback2)(bool param, void *userData);

void TheirLibrary::Function1(Callback1 callback, void *userData);
void TheirLibrary::Function2(Callback2 callback, void *userData);

class MyClass
{
bool MyMethod1(void *userData);
int MyMethod2(bool someParam, void *userData);

void DoSomething()
{
Function1(CreateGenericCPointer(&MyClass::MyMethod1), &MyClass);
Function2(CreateGenericCPointer(&MyClass::MyMethod2), &MyClass);
}
}

CreateGenericCPointer 的有效实现是什么?

最佳答案

我不完全清楚您正在寻找什么级别的通用性,但也许这会让您开始:

typedef std::function<DWORD()> ThreadFuncT;

DWORD WINAPI RunThreadFunction(void* data)
{
std::unique_ptr<ThreadFuncT> tf(static_cast<ThreadFuncT*>(data));
return (*tf)();
}

template<typename F>
ThreadFuncT* MakeThreadFunction(F&& f)
{
return new ThreadFuncT(std::forward<F>(f));
}

// ...

auto myClass = std::make_shared<SomeClass>(/* ... */);
CreateThread(
nullptr,
0,
RunThreadFunction,
MakeThreadFunction([=]() { return myClass->ThreadFunction(nullptr); }),
0,
nullptr
);

请注意,因为 myClassstd::shared_ptr<>并被值(value)捕获,底层 SomeClass即使 myClass 的生命周期也会正常终止在线程完成执行之前超出范围(只要 RunThreadFunction 最终被调用)。


编辑:这是另一种方法(未经测试,可能是语法错误):

template<typename R>
R WINAPI RunThreadFunction(void* data)
{
typedef std::function<R()> ThreadFuncT;
std::unique_ptr<ThreadFuncT> tf(static_cast<ThreadFuncT*>(data));
return (*tf)();
}

template<typename F>
auto MakeThreadFunction(F&& f) -> std::function<decltype(f())()>*
{
return new std::function<decltype(f())()>(std::forward<F>(f));
}

// ...

auto myClass = std::make_shared<SomeClass>(/* ... */);
auto f = [=]() { return myClass->ThreadFunction(nullptr); };
CreateThread(
nullptr,
0,
RunThreadFunction<decltype(f())>,
MakeThreadFunction(std::move(f)),
0,
nullptr
);

关于c++ - 从方法指针动态创建通用函数指针,推导返回值和参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8661718/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com