У меня есть этот вспомогательный класс, который я использую для вызова методов-членов для кода, ожидающего статических функций C. Эта конкретная «версия» совместима с обратными вызовами Windows LPTHREADROUTINE, принимая в качестве параметра функцию DWORD (class::method) (void *)
, вызываемую следующим образом:
CreateThread(NULL, 0, runThreadFunction<SomeClass>, makeThreadInfo(&myClass, &SomeClass::ThreadFunction, NULL), 0, NULL);
Я хочу сделать все это универсальным, и я знаю, что это можно сделать с помощью нового стандарта С++ 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 примерно так:
template <typename C, typename R, typename... P>
void* MakeThreadInfo(C* o, std::function<R(P&...)> f, void* d)
Казалось бы, это правильный путь, но я не смог передать это значение вверх по течению.
Вот что я хочу получить:
Имея класс MyClass с методом MyMethod и обратный вызов типа возвращаемого значения variable и один или несколько параметров различных типов (последним из которых является 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
?
MakeThreadInfo
универсальным? Вы хотите поддерживать функторы? - person outis   schedule 29.12.2011MakeThreadInfo
работал для методов, которые могут принимать аргументы, отличные отvoid*
, и возвращать что-то, кромеDWORD
s? Обратите внимание, что SO не является форумом, а комментарии не предназначены для обсуждения. Уточнения должны быть отредактированы в вопросе. - person outis   schedule 29.12.2011