64,647
社区成员
发帖
与我相关
我的任务
分享
#include <iostream>
#include <unordered_map>
using namespace std;
void test() { printf("123\n"); }
void test(int i) { printf("123 i is %d\n",i); }
class regFunc {
unordered_map<string, void*> unmap_name_funcinfo;
public:
template<class T>
void insert(const string& funcName, T funcAddr) {
unmap_name_funcinfo.insert({ funcName ,(void*)funcAddr });
}
template<class T,class ...ARGS>
auto run(const string& funcName, ARGS... args){
auto funcObj = (T)unmap_name_funcinfo.find(funcName)->second;
return funcObj(args...);
}
};
int main() {
typedef void(*iterFunc1)();
typedef void(*iterFunc2)(int);
unordered_map<string, void*> map;
regFunc reg;
reg.insert("test", ((iterFunc1)test));
reg.insert("test@i", ((iterFunc2)test));
reg.run<iterFunc1>("test");
reg.run<iterFunc2>(string("test@i"),20);
}
class RT{ };
class LRT :public RT
{ public: long v; };
class STRINGRT :public RT
{ public: std::string v; };
LRT* r1(va_list ap)
{
auto a =new LRT;
a->v =1;
return a;
}
//STRINGRT* r2(LPCSTR s)
STRINGRT* r2(va_list ap)
{
LPCSTR s =*(LPCSTR*)ap;
auto a =new STRINGRT;
a->v.assign(s);
return a;
}
typedef RT* (*RTVSFUN)(va_list ap);
static const RTVSFUN FUS[] =
{
(RTVSFUN)r1, (RTVSFUN)r2,
};
RT* Run(int idx, ...)
{
va_list ap;
va_start(ap, idx);
RT* v = FUS[idx](ap);
va_end(ap);
return v;
}
int _tmain(int argc, _TCHAR* argv[])
{
LRT* r1Rt = static_cast<LRT*>(Run(0));
STRINGRT* r2Rt = static_cast<STRINGRT*>(Run(1, "That's it!"));
cout <<r1Rt->v <<endl;
cout <<r2Rt->v.c_str()<<endl;
delete r1Rt;
delete r2Rt;
printf("The End\n");
::getchar();
return 1;
}
double add(int a, double b)
{
return a + b;
}
double mul(int a, double b)
{
return a * b;
}
void test()
{
try{
ObjectList args;
args.add(toObject(12));
args.add(toObject(6));
Object* result = dispatcher.call("add", args);
delete result;
result = dispatcher.call("mul", args);
delete result;
}catch (Exception& e){
e.printStackTrace();
}
}
详细代码见:
testBaseType(): https://github.com/javeme/brpc/blob/master/test.cpp#L299
testDispatcher(): https://github.com/javeme/brpc/blob/master/test.cpp#L537
这种动态调用(所谓反射)的典型使用场景是RPC, ORM(setter/getter)等.
更多关于C++实现RPC调用方法见: https://github.com/javeme/brpc
#include <stdio.h>
#include <assert.h>
#include <string>
#include <unordered_map>
using namespace std;
class Invoker
{
public:
virtual ~Invoker() {}
};
template<typename R, typename... Args>
class InvokerT : public Invoker
{
public:
typedef R(*FuncT)(Args...);
public:
InvokerT(FuncT func) : _func(func) {}
~InvokerT() {}
R Run(Args&& ... args)
{
return _func(std::forward<Args>(args)...);
}
private:
FuncT _func;
};
class regFunc
{
public:
template<typename R, typename... Args>
void insert(const std::string & name, R(*func)(Args...))
{
auto invoker = new InvokerT<R, typename std::decay<Args>::type...>(func);
assert(invoker);
_invokers[name] = invoker;
}
template<typename R, typename... Args>
R run(const string & name, Args&& ... args)
{
auto it = _invokers.find(name);
if (it == _invokers.end())
{
assert(false);
return R();
}
auto real_invoker = dynamic_cast<InvokerT<R, typename std::decay<Args>::type...>*>(it->second);
if (real_invoker == nullptr)
{
assert(false);
return R();
}
return real_invoker->Run(std::forward<Args>(args)...);
}
private:
unordered_map<string, Invoker*> _invokers;
};
void test()
{
printf("123\n");
}
int test(int i)
{
printf("123 i is %d\n", i);
return 0;
}
int main()
{
typedef void(*iterFunc1)();
typedef int(*iterFunc2)(int);
regFunc reg;
reg.insert("test", ((iterFunc1)test));
reg.insert("test@i", ((iterFunc2)test));
reg.run<void>("test");
reg.run<int>("test@i", 20);
return 0;
}
void test1() { printf("123\n"); }
void test2(int i) { printf("123 i is %d\n", i); }
int main()
{
typedef void(*iterFunc1)();
regFunc reg;
reg.insert("test1", &test1);
reg.insert("test2",&test1);
reg.run_void("test1");
reg.run_void("test2", 20);
return 0;
}
[/quote]
不是一样的吗,&test1,&test1只能在编译时确定,无法在运行时传入[/quote]
这个是,你要把运行时调用的函数先注册了,上面代码实际是放到一个map里
void test1() { printf("123\n"); }
void test2(int i) { printf("123 i is %d\n", i); }
int main()
{
typedef void(*iterFunc1)();
regFunc reg;
reg.insert("test1", &test1);
reg.insert("test2",&test1);
reg.run_void("test1");
reg.run_void("test2", 20);
return 0;
}
[/quote]
不是一样的吗,&test1,&test1只能在编译时确定,无法在运行时传入
void test1() { printf("123\n"); }
void test2(int i) { printf("123 i is %d\n", i); }
int main()
{
typedef void(*iterFunc1)();
regFunc reg;
reg.insert("test1", &test1);
reg.insert("test2", &test2);
reg.run_void("test1");
reg.run_void("test2", 20);
return 0;
}