C ++ to C调用:类型'void(MyClass ::)(u_char *,)'的参数与'void(*)(u_char *)'不匹配

时间:2010-11-08 18:07:25

标签: c++

我生锈的C ++技能在失败之后失败了:

#include <pcap.h>
...
void Sniff::pcap_listen() {
 pcap_t *loc;
 char *dev;
 dev = pcap_lookupdev(errbuf);
 loc = pcap_open_live(dev,BUFSIZ,0,-1,errbuf);
 pcap_loop(loc,-1,pcap_callback,NULL);
}
  

错误:类型为'void的参数   (Sniff ::)(u_char *,const pcap_pkthdr *,   const u_char *)'与'无效'相匹配   (*)(u_char *,const pcap_pkthdr *,const   u_char *)”

在.h中添加/删除'静态'定义:无效。

++另一个问题:

listener = g_thread_create(pcap_listen, NULL, FALSE, NULL);

很多变种的::,&amp;,这个......经过测试,最有用的信息是:

  

src / main.cpp:281:错误:参数   类型'void *(Sniff ::)(void *)'没有   匹配'void *()(void *)'

5 个答案:

答案 0 :(得分:5)

你不能pass a pointer to a member function to something that's expecting a function pointer。从根本上说,指向成员函数的指针是与函数指针完全不同的类型。两者之间没有平凡的转换,因为没有this指针,所以它永远不会是一个,这是调用非静态成员函数所必需的。

简单地添加static在技术上也没有解决问题,因为它不具有C链接,可能是符合实现的问题。在大多数实现中,这表现良好,但一般不便携,便携式解决方案需要使用

extern "C" {
   void my_callback() {
   }
}

<强>更新

鉴于您尝试调用的两个函数似乎都采用void*“用户参数”,您可以将其与变量一起使用,以将指针传递给您的类的实例,例如:这些方面的东西:

class CallbackHandler {
public:
   void my_callback();   
};

extern "C" {
   void callback_wrapper(void *arg) {
      static_cast<CallbackHandler*>(arg)->my_callback();
   }
}

void start_pcap_listen(CallbackHandler* receiver) {
   pcap_t *loc;
   char *dev;
   dev = pcap_lookupdev(errbuf);
   loc = pcap_open_live(dev,BUFSIZ,0,-1,errbuf);
   pcap_loop(loc,-1,callback_wrapper,receiver);   
}

它不漂亮,但它有效。

答案 1 :(得分:1)

在C ++中,成员函数和“自由”函数指针不可互换。您的pcap_callback函数似乎是class Sniff的实例(非静态)成员。如果它是静态成员,那么您必须使用类名限定它。

pcap_loop(loc,-1,Sniff::pcap_callback,NULL);

答案 2 :(得分:1)

我认为你应该从这些编译器消息中闪现的是指向成员的指针与函数指针不同。

是否将您的成员函数设置为静态,从而将其地址从“指向成员的指针”转换为“指向函数的指针”实际上将解决您的问题,这完全取决于您的需求。

答案 3 :(得分:1)

当API需要全局函数指针时,您正在传递指向成员函数的指针。您已经写过在标题中添加static定义没有效果,它应该解决问题,因为静态函数不是成员函数(它是全局的)。当函数是静态的时,你可以分享它不起作用的原因吗?

答案 4 :(得分:1)

通常可以通过使用ThreadFunction类来完成。我们将给它一个非虚方法“invoke”和一个虚拟方法“run”。这方面的一些变化将起作用:

class ThreadFunction
{
public:
   virtual ~ThreadFunction();
   void invoke( bool joinable );

protected: // or private
   virtual void* run() = 0;
   friend void * my_thread_func( void * );

   GThread * gthread;   
   GError * error;
};

//在你的cpp中

void* my_thread_func( void * tf )
{
   ThreadFunction * func = static_cast< ThreadFunction * >(tf);
   return tf->run();
}

void ThreadFunction::invoke( bool joinable )
{
   gthread = g_thread_create( my_thread_func, this, joinable, &error );
}

这只是方法的概述。您将创建从ThreadFunction派生的线程。 (joinable可能是您实现的一个功能,而不是传入的参数)。