我正在编写一个托管的C ++程序,它运行用户编写的动态编译代码。从C代码中捕获并处理/忽略某些典型异常绝对至关重要。 为此,我从结构化异常处理块中调用C代码。由于这个块的性质和语义(以及从哪里调用),我将实际调用与它自己的函数分开:
template <typename ret_type, class func>
static ret_type Cstate::RunProtectedCode(func function) {
ret_type ret = 0;
__try {
ret = function();
}
__except(ExceptionHandler(GetExceptionCode(), ExceptionStatus::CSubsystem)) {
fprintf(stderr, "First chance exception in C-code.\n");
}
return ret;
}
它应该如此有效:
RunProtectedCode<int>(entry);
但是有可能塑造这个,所以我可以调用具有可变参数量的函数 - 可能通过一些使用异域函子(只是要求显然它不能有析构函数)?我正在使用MSVC ++ 2010。
答案 0 :(得分:2)
如果你可以使用C ++ 11,你可以使用可变的tempaltes来实现它。
template <typename ret_type, class func, typename... Args>
static ret_type Cstate::RunProtectedCode(func function, Args... args) {
ret_type ret = 0;
__try {
ret = function(args...);
}
__except(ExceptionHandler(GetExceptionCode(), ExceptionStatus::CSubsystem)) {
fprintf(stderr, "First chance exception in C-code.\n");
}
return ret;
}
你可以称之为
RunProtectedCode<int>(entry2, 1, 2);
RunProtectedCode<int>(entry3, 1, "a", 3);
您可以使用std :: function来简化它(种类)。
template <class func, typename... Args>
static
typename func::result_type Cstate::RunProtectedCode(func function, Args... args) {
typename func::result_type ret = typename func::result_type();
__try {
ret = function(args...);
}
__except(ExceptionHandler(GetExceptionCode(), ExceptionStatus::CSubsystem)) {
fprintf(stderr, "First chance exception in C-code.\n");
}
return ret;
}
你可以称之为
std::function<int(int,int,int)> entry_f = entry;
RunProtectedCode(entry_f,1,2,3);
答案 1 :(得分:0)
您可以将所有参数绑定到您的函数,使其成为有效的0-ary仿函数,例如使用std::bind
(在VC2010中可用)或boost::bind
(我更喜欢这个,因为VC实现包含损坏的std::cref
)。绑定可以在传递给RunProtectedCode
之前在重载函数中完成,例如,像这样的东西:
template<typename R>
R(*f)() wrap(R(*f)())
{
return f;
}
template<typename R, typename A>
boost::function<R(A)> wrap(R(*f)(), A a)
{
return boost::bind(f, a);
}
template<typename R, typename A1, typename A2>
boost::function<R(A1, A2)> wrap(R(*f)(), A1 a1, A2 a2)
{
return boost::bind(f, a1, a2);
}