首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >将C++函数指针转换为c函数指针

将C++函数指针转换为c函数指针
EN

Stack Overflow用户
提问于 2013-11-06 17:19:00
回答 6查看 25.3K关注 0票数 28

我正在使用C库开发一个C++应用程序。我必须向C库发送一个指向函数的指针。

这是我的班级:

代码语言:javascript
复制
 class MainWindow : public QMainWindow {  
     Q_OBJECT  
     public:  
     explicit MainWindow(QWidget *parent = 0);  
     private:  
     Ui::MainWindow *ui;
     void f(int*);

 private slots:
     void on_btn_clicked(); 
};

这是我的on_btn_clicked函数:

代码语言:javascript
复制
void MainWindow::on_btn_clicked()
{
    void (MainWindow::* ptfptr) (int*) = &MainWindow::f;

    c_library_function(static_cast<void()(int*)>(ptfptr), NULL);

}

C函数应该有一个指向这样的函数的指针: void f(int*)。但是上面的代码不起作用,我无法成功地将我的f成员函数转换为所需的指针。

有人能帮帮忙吗?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2013-11-06 17:24:57

如果我没记错的话,只有类的静态方法可以通过指向函数语法的“普通”C指针来访问。所以试着让它成为静态的。指向一个类的方法的指针需要额外的信息,比如"object“(this),它对纯C方法没有任何意义。

here的常见问题解答对你的问题有很好的解释和可能的(丑陋的)解决方案。

票数 13
EN

Stack Overflow用户

发布于 2013-11-06 18:36:54

不能将函数指针传递给非静态成员函数。您可以做的是创建一个使用实例参数进行调用的静态或全局函数。

下面是一个很有用的例子,它使用了一个有两个成员的helper类:一个函数包装器和一个调用包装器的回调函数。

代码语言:javascript
复制
template <typename T>
struct Callback;

template <typename Ret, typename... Params>
struct Callback<Ret(Params...)> {
    template <typename... Args>
    static Ret callback(Args... args) { return func(args...); }
    static std::function<Ret(Params...)> func;
};

// Initialize the static member.
template <typename Ret, typename... Params>
std::function<Ret(Params...)> Callback<Ret(Params...)>::func;

使用它,您可以存储任何可调用的、甚至是非静态的成员函数(使用std::bind),并使用Callback::callback函数转换为c指针。例如:

代码语言:javascript
复制
struct Foo {
    void print(int* x) { // Some member function.
        std::cout << *x << std::endl;
    }
};

int main() {
    Foo foo; // Create instance of Foo.

    // Store member function and the instance using std::bind.
    Callback<void(int*)>::func = std::bind(&Foo::print, foo, std::placeholders::_1);

    // Convert callback-function to c-pointer.
    void (*c_func)(int*) = static_cast<decltype(c_func)>(Callback<void(int*)>::callback);

    // Use in any way you wish.
    std::unique_ptr<int> iptr{new int(5)};
    c_func(iptr.get());
}
票数 19
EN

Stack Overflow用户

发布于 2014-03-19 01:33:41

@Snps的答案很棒。我用一个创建回调的maker函数对它进行了扩展,因为我总是使用不带参数的void回调:

代码语言:javascript
复制
typedef void (*voidCCallback)();
template<typename T>
voidCCallback makeCCallback(void (T::*method)(),T* r){
  Callback<void()>::func = std::bind(method, r);
  void (*c_function_pointer)() = static_cast<decltype(c_function_pointer)>(Callback<void()>::callback);
  return c_function_pointer;
}

从那时起,您可以在类内或其他任何地方创建普通的C回调,并让成员调用:

代码语言:javascript
复制
voidCCallback callback = makeCCallback(&Foo::print, this);
plainOldCFunction(callback);
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19808054

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档