函数指针问题.如何有效地与C API接口(即.GSL)来自C++类
A function pointer issue. How to efficiently interface with C API (ie. GSL) from C++ class?
这个问题似乎以前被问过很多次,例如这里1,这里2和这里3。
我正在尝试做的是,将 C-Struct gsl_function
的成员function
设置为我的类的成员函数。
class MyClass{
double foo(double x)
{
return ...;
}
double bar(double x)
{
...
gsl_function F;
// Problem I cant do this (compiler error)
F.function = &(this->foo);
}
};
上面的第三个链接提供了一个解决方案,我认为它基于这里描述的包装方法4。
所以我的问题是我能做得更好吗?有没有更简单的方法?例如,可能通过使用 Boost 的函数和 Bind 对象。
我正在权衡使用 gsl 包装器的选项,例如 o2scl。但是我有点不情愿,因为如果包装器维护不好,我可能会稍后付出代价。有什么建议吗?
由于 GSL 允许您传入任意参数,因此您可以滥用它来保存指向相关实例的指针。 然后使用静态成员函数转发到成员函数:
class MyClass
{
double foo(double x)
{
...
}
static double foo_wrapper(double x, void *params)
{
return static_cast<MyClass*>(params)->foo(x);
}
double bar(double x)
{
...
gsl_function F;
F.function=&MyClass::foo_wrapper;
F.params=this;
// invoke GSL function passing in F
...
}
};
你能做得更好吗? 有没有更简单的方法? 没有。 您采取的任何方法都将在某个地方的掩护下执行此操作。
但是你可以写一个简单的包装器来隐藏其中的一些:
class gsl_function_pp : public gsl_function
{
public:
gsl_function_pp(boost::function<double(double)> const& func) : _func(func)
{
function=&gsl_function_pp::invoke;
params=this;
}
private:
boost::function<double(double)> _func;
static double invoke(double x, void *params)
{
return static_cast<gsl_function_pp*>(params)->_func(x);
}
};
这应该会给你(由于涉及多个间接寻址,可能会有适度的性能损失)你想要的功能类型:
class MyClass
{
double foo(double x)
{
...
}
double bar(double x)
{
gsl_function_pp F(boost::bind(&MyClass::foo, this, _1));
// invoke GSL function passing in F
...
}
};
需要注意的是,您必须确保任何gsl_function_pp
对象在 GSL 可能调用它的整个时间内都保持在范围内。 因此,不要尝试在一个函数中设置根查找器/等(使用本地gsl_function_pp),返回,然后在另一个函数中执行根查找迭代 - 你会崩溃或更糟。
相关文章:
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- 2D数组来自文本输入,中间有空格
- 通过继承类使用来自不同命名空间的运算符
- Cuda C++:设备上的Malloc类,并用来自主机的数据填充它
- C++:来自外部文件的Trivia
- 如何处理来自核心指南检查器的关于gsl::at的静态分析警告
- 针对遗留库的链接:来自预制makefile的-lgfortranbegin
- 将gsl c++程序与"英特尔MKL"链接
- 如何在C++中正确引用来自不同类的类的对象?
- Qt中来自不同功能的按钮引用
- C++包含来自 #include "DevEngine/Core.h" 的错误
- Eigen c++ 三角形来自
- 来自 DLL 的函数调用 [表观调用的括号前面的表达式必须具有(指向-)函数类型]
- 来自 Android 应用程序内部的 boost 类型的 boost::wrapexcept<boost::system::system_error> 的未捕获异常
- C++ 警告:将新创建的 gsl::owner<> 分配给非所有者
- 中止信号来自 C++ 中的中止(3) (SIGABRT)
- 如何多次询问来自QML对话框的输入?
- 如何强制 Thrift 仅接受来自本地主机的连接
- 使 ld 忽略来自 /etc/ld.so.conf 的目录
- 函数指针问题.如何有效地与C API接口(即.GSL)来自C++类