我怎样才能通过C++;C API的成员函数作为参数 在我的C++程序中,我需要调用这个cAPI: GConn* gnet_conn_new (const gchar *hostname, gint port, GConnFunc func);

我怎样才能通过C++;C API的成员函数作为参数 在我的C++程序中,我需要调用这个cAPI: GConn* gnet_conn_new (const gchar *hostname, gint port, GConnFunc func);,c++,C++,其中,GConnFunc定义为: void (*GConnFunc) (GConn *conn); 我的问题是,如果我有一个C++类,并且有一个成员函数,比如: Class A { public: A(); void my_func (GConn* conn); } 在我的A::A()构造函数中,如何将this->myfunc作为GConnFunc参数传递给gnet\u conn\u new 谢谢。您需要一个包装函数来处理此问题,或者您可以将my_func设置为静态(假设它不需

其中,GConnFunc定义为:

void (*GConnFunc) (GConn *conn);
我的问题是,如果我有一个C++类,并且有一个成员函数,比如:

Class A {
 public:
   A();
   void my_func (GConn* conn);
}
在我的
A::A()
构造函数中,如何将
this->myfunc
作为
GConnFunc
参数传递给
gnet\u conn\u new


谢谢。

您需要一个包装函数来处理此问题,或者您可以将my_func设置为静态(假设它不需要访问任何实例变量)。

大多数API都提供指针大小的“用户数据”参数,如下所示:

GConn* gnet_conn_new (const gchar *hostname, 
                  gint port, 
                  GConnFunc func,
                  void* user_data); 
void my_func(GConn *conn, void* user_data)
{
    ((MyClass*)user_data)->MyMemberFunc(conn);
}
这将允许您在user_数据中传递一个实例,并将您的C函数转发给成员函数,如下所示:

GConn* gnet_conn_new (const gchar *hostname, 
                  gint port, 
                  GConnFunc func,
                  void* user_data); 
void my_func(GConn *conn, void* user_data)
{
    ((MyClass*)user_data)->MyMemberFunc(conn);
}

也许您的API在某个地方有一个替代或类似的“用户数据”参数。否则,你不能真正地做它没有全局或静力学。< /p> < p>一个C++类中的非静态成员函数有一个隐藏的“这个”参数。如果可以假设将其转换为C,则函数将转换为:

void A_my_func (A * const this, GConn* conn);
虽然您可以使用上面的原型编写一个包装器函数,并将指向它的指针传递给一个C函数,但实际上并没有一种方法可以在代码中自动进行这种转换


通常的处理方法是传递自由(非成员)函数或类静态函数。这两种类型都没有隐藏参数。

简而言之,您不能

长答覆:

如果API为您提供了足够的调用余地,您可以装配一个函数,只需注册并作为中介调用即可。通常,回调函数允许您包含传递给该函数的额外数据以及进行回调的对象生成的信息。它通常被称为“客户端数据”,类型为void*或long。在这种情况下,您可以简单地使用这些数据来包含足够的信息,以便在您想要的实例上调用您想要的函数,例如抛出boost::function

请注意,委托给成员函数的中间函数可以是静态成员或自由函数

不幸的是,你在这里没有这个选择,所以你的工作将加倍艰难。您确实需要某种方法来确保正确的实例得到了消息,并且您无法从回调的数据中识别该实例。有两个选项可能对您有效,也可能对您无效:

  • 请确保从不使用多个实例作为回调目标。将此实例注册到某种类型的单实例或全局实例,该实例跟踪要引用此类型事件的时间的一个实例

  • 注册尽可能多的实例,确保它们都得到消息,然后要么处理,要么不处理。在这里,您可以使用一种“责任链”,让目标有机会处理事件,然后返回一些信息,让循环知道它应该继续还是停止

  • 总之,没有直接的方法去做你想做的事情,但是如果你考虑了选择的话,可能会得到你需要的答案。任何用作提供给C API函数的回调函数都必须作为函数指针引用,而不是任何类型的成员指针…不幸的是,也不是函子。C不知道如何处理这些事情,所以您的回调必须是自由函数或静态成员。

    建议的副本()似乎不是副本。它讨论了在C++上下文中传递指向成员的指针。