我有一段代码,它以 XML 的形式从 Flash Player 获取消息,将它们解析为函数和参数,并调用该函数的已注册回调。 我想要替换的代码片段是做得很好(几乎)的通用回调机制: code for the generic callback implementation of flashSDK (ASInterface.inl) .
问题是这段代码是为闪存编写的,我想更换闪存并使用具有相同接口(interface)的其他服务。此回调机制是否有任何标准实现(std?boost?其他开源的东西?)?
此代码实现了通用回调机制,您可以在映射中使用参数数量和类型注册函数:
void SomethingHappened(int a, int b) {print a + b;}
void SomethingElseHappened(string abcd) {print abcd;}
callbacks["SomethingHappened"] = &SomethingHappened;
callbacks["SomethingElseHappened"] = &SomethingElseHappened;
然后搜索它并使用参数数组调用:
Callbacks::iterator itCallback = callbacks.find(functionName);
if (itCallback != callbacks.end())
{
HRESULT result = itCallback->second.Call(arguments, returnValue);
}
完整使用示例:
//init callbacks
std::map<std::wstring, Callback> callbacks;
void SomethingHappened(int a, int b) {print a + b;}
void SomethingElseHappened(string abcd) {print abcd;}
callbacks[functionName] = &SomethingHappened;
void MessageArrived(string xmlInput)
{
string functionName = parseFunctionName(xmlInput);
Callbacks::iterator itCallback = callbacks.find(functionName);
if (itCallback != callbacks.end())
{
//parse arguments
std::vector<std::wstring> args;
_Args::split(xml, args);
ASValue::Array arguments;
for (size_t i = 0, s = args.size(); i < s; ++i)
{
ASValue arg; arg.FromXML(args[i]);
arguments.push_back(arg);
}
ASValue returnValue;
//***this is where the magic happens: call the function***
HRESULT result = itCallback->second.Call(arguments, returnValue);
return result;
}
}
最佳答案
您可能需要一个 std::function
的包装器,例如:
template <typename T> struct Tag{};
// Convert ASValue to expected type,
// Possibly throw for invalid arguments.
bool Convert(Tag<Bool>, AsValue val) { return (Boolean)val; }
int Convert(Tag<int>, AsValue val) { return (Number)val; }
// ...
struct Callback
{
private:
template <std::size_t ... Is, typename Ret, typename ... Ts>
static Ret call_impl(Ret(* func)(Ts...), std::index_sequence<Is...>)
{
if (arr.size() != sizeof...(Is)) throw std::invalid_argument{};
return func(Convert(tag<Ts>{}, arr[Is])...);
}
public:
template <typename Ret, typename ... Ts>
Callback(Ret(* func)(Ts...)) : Call{[func](ASValue::Array arr, ASValue& ret)
{
try
{
ret = Callback::call_impl(func, std::make_index_sequence<sizeof(...(Ts)>());
return S_OK;
} catch (...) {
return E_INVALIDARG;
}
}}
{}
std::function<HRESULT(ASValue::Array, ASValue&)> Call;
};
std::index_sequence
是 C++14,但您可能会在 SO 上找到实现。
关于C++ 通用回调实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66329804/