我有一些这样的代码,我想加载一个 dll 文件并从中选择一个函数来执行。:
// this is function's parameter define
struct Parameter
{
std::string type; // int
std::string value; // Local.X
};
using ParameterList = std::list<Parameter>;
// this is function's moudle define
struct ModuleFunction
{
std::string path; // dll file path
std::string rawName; // ?Add@@YAHHH@Z
std::string undName; // int __cdecl Add(int,int)
std::string returnType; // int
std::string callConvention; // __cdecl
std::string name; // Add
ParameterList params;
};
// this is value define. a value is created by manual. I can get it from DataManager.
struct Value
{
std::string name; // value name, like: Local.X
std::string type; // value type, like: int, double, string, ...
void* value; // stored value, like: 5, 1.0, "abc", ...
int toInt() const { ... };
double toDouble() const { ... };
std::string toString() const { ... };
};
// run module function
void run(const ModuleFunction& module)
{
DllCaller calller(module.path); // load dll from module.path
/*
run DllCaller::dllCall() according to function's param counts
DllCaller::dllCall() is a template function. it has variadic parameters. like:
template <class RETTYPE = void, class... PARAMTYPES>
RETTYPE DllCaller::dllCall(const string& callConvention, const string& fnName, const PARAMTYPES& ...params) { ... };
*/
switch (module.params.size())
{
case 0:
{
if (module.returnType == "int")
auto ret = caller.dllCall<int>(module.callConvention, module.rawName);
else if (module.returnType == "double")
auto ret = caller.dllCall<double>(module.callConvention, module.rawName);
else if (module.returnType == "string")
auto ret = caller.dllCall<string>(module.callConvention, module.rawName);
}
break;
case 1:
{
const Parameter& param = module.params[0];
const Value& value = DataManager::getValue(param.value);
if (module.returnType == "int")
{
if (value.type == "int")
auto ret = caller.dllCall<int>(module.callConvention, module.rawName, value.toInt());
else if (value.type == "double")
auto ret = caller.dllCall<int>(module.callConvention, module.rawName, value.toDouble());
else if (value.type == "string")
auto ret = caller.dllCall<int>(module.callConvention, module.rawName, value.toString());
}
else if (module.returnType == "double")
{
if (value.type == "int")
auto ret = caller.dllCall<double>(module.callConvention, module.rawName, value.toInt());
else if (value.type == "double")
auto ret = caller.dllCall<double>(module.callConvention, module.rawName, value.toDouble());
else if (value.type == "string")
auto ret = caller.dllCall<double>(module.callConvention, module.rawName, value.toString());
}
else if (module.returnType == "string")
{
if (value.type == "int")
auto ret = caller.dllCall<string>(module.callConvention, module.rawName, value.toInt());
else if (value.type == "double")
auto ret = caller.dllCall<string>(module.callConvention, module.rawName, value.toDouble());
else if (value.type == "string")
auto ret = caller.dllCall<string>(module.callConvention, module.rawName, value.toString());
}
}
break;
case 2:
break;
case 3:
break;
case 4:
break;
}
}
因为我不知道函数有多少参数,也不知道参数类型是什么,所以代码非常“难”和“丑”以适应各种情况。是否可以将参数类型字符串转换为真实类型并传递给函数?或者一些更好的解决方案?