代码之家  ›  专栏  ›  技术社区  ›  kagali-san

C++C调用:类型“空格(MyCase::)(U-CHAR *)”的参数与“空隙”(*)(U-CHAR *)不匹配

c++
  •  2
  • kagali-san  · 技术社区  · 15 年前

    #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类型的参数 (嗅嗅:)(u_char*,const pcap_pkthdr*, const u__char*)与void不匹配 字符*)

    在.h中添加/删除“static”定义:无效。

    ++另一个问题:

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

    src/main.cpp:281:错误:参数 类型void*(Sniff::)(void*)不 匹配无效*( *)

    5 回复  |  直到 15 年前
        1
  •  5
  •   Flexo - Save the data dump sunny moon    15 年前

    你不能 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);   
    }
    

        2
  •  1
  •   Nick Meyer    15 年前

    C++中的成员函数和“自由”函数指针是不可互换的。你的 pcap_callback class Sniff . 如果它是静态成员,则必须用类名限定它。

    pcap_loop(loc,-1,Sniff::pcap_callback,NULL);
    
        3
  •  1
  •   Edward Strange    15 年前

    我认为您应该从这些编译器消息中了解到,指向成员的指针与函数指针不同。

    是否使成员函数成为静态的,从而将其地址从“指针到成员”转换为“指针到函数”,实际上会解决您的问题,这完全取决于您的需要是什么。

        4
  •  1
  •   yonilevy    15 年前

    当API需要全局函数指针时,您正在将指针传递给成员函数。你已经写过了 static

        5
  •  1
  •   CashCow    15 年前

    通常这可以通过使用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派生的线程。(可连接可能是实现的一个特性,而不是传入的参数)。