首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >“void*(.)(void*)”类型的参数与“void* (*)(void*)”不匹配

“void*(.)(void*)”类型的参数与“void* (*)(void*)”不匹配
EN

Stack Overflow用户
提问于 2014-06-19 15:41:47
回答 1查看 2.2K关注 0票数 0

我目前正在开发GNU电台的一个集团,我想使用一个线程。这个线程可以从UDP套接字中获取数据,这样我就可以在我的GNU无线电单元中使用它。“一般工作”功能是负责所有信号和数据处理的功能。

主源文件的组织方式如下:

代码语言:javascript
复制
namespace gr {
    namespace adsb {

    out::sptr
    out::make()
    {
        return gnuradio::get_initial_sptr
        (new out_impl());
    }

    /*
     * UDP thread
     */
    void *task_UdpRx (void *arg)
    {
        while(true)
        {
            printf("Task UdpRx\n\r");
            usleep(500*1000);
        }
       pthread_exit(NULL);
    }

    /*
    * The private constructor
    */
    out_impl::out_impl()
        : gr::block("out",
                gr::io_signature::make(1, 1, sizeof(int)),
                gr::io_signature::make(1, 1, sizeof(char)))
    {
        pthread_t Thread_UdpRx;

        //Thread init
        if(pthread_create(&Thread_UdpRx, NULL, task_UdpRx, NULL))
        {
            err("Pthread error");
        }
        else
        {
            printf("UDP thread initialization completed\n\r");
        }
    }

    /*
    * Our virtual destructor.
    */
    out_impl::~out_impl()
    {
    }

    void out_impl::forecast (int noutput_items, gr_vector_int &ninput_items_required)
    {
        ninput_items_required[0] = noutput_items;
    }

    int out_impl::general_work (int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items)
    {
        const int *in = (const int *) input_items[0];
        char *out = (char *) output_items[0];

        // Do <+signal processing+>
        for(int i = 0; i < noutput_items; i++)
        {
            printf("General work\n\r");
        }/* for < noutput_items */

        // Tell runtime system how many input items we consumed on
        // each input stream.
        consume_each (noutput_items);

        // Tell runtime system how many output items we produced.
        return noutput_items;
    } /* general work */

    } /* namespace adsb */
} /* namespace gr */`

我遇到的问题是,当我试图编译时,我会得到以下错误:

代码语言:javascript
复制
In constructor ‘gr::adsb::out_impl::out_impl()’:
error: argument of type ‘void* (gr::adsb::out_impl::)(void*)’ does not match ‘void* (*)(void*)’

此错误引用行,它涉及到task_UdpRx:

代码语言:javascript
复制
if(pthread_create(&Thread_UdpRx, NULL, task_UdpRx, NULL))

有人知道吗?

如果需要的话,不要犹豫要求更多的细节。我所显示的代码是我所能做的最短的代码,以便您能够得到最好的理解。

谢谢!

EN

回答 1

Stack Overflow用户

发布于 2014-06-19 16:15:07

不能将指向成员函数的指针传递给pthread_create()

您需要一个免费的函数:

代码语言:javascript
复制
void *thread_start(void *object)
{
    gr::adsb::out_impl *object = reinterpret_cast<gr::adsb::out_impl *>(object);
    object.task_UpdRx(0);
    return 0;
}

或者,您需要将此函数传递给pthread_create(),并将this指针作为数据参数传递:

代码语言:javascript
复制
if (pthread_create(&Thread_UdpRx, NULL, thread_start, this))

我保留滥用reinterpret_cast<>()的权利--用正确的表示法代替。我对在构造函数中启动线程有保留,但这是一个应该工作的方案的大纲。

在2014-06-25年度更新代码之后

代码仍然不是MCVE。我不能复制和编译它。有许多标题缺失。未定义/声明outout_impl类型。一些GNU无线电继承的东西可能会被忽略。

这是我的MCVE版本。它并不完美,因为它不会重现你的问题。它在Ubuntu12.04 LTS导数上用GCC 4.9.0进行了清晰的编译。它假设您有一个定义函数<err.h>的标头err()。我不确定析构函数是否是MCVE所必需的(并且删除它将消除另外5行左右)。

来源

代码语言:javascript
复制
#include <cstdio>
#include <pthread.h>
#include <unistd.h>
#include <err.h>

namespace gr
{
    namespace adsb
    {
        class out_impl
        {
        public:
            out_impl();
            virtual ~out_impl();
        };

        void *task_UdpRx(void *arg)
        {
            while (true)
            {
                printf("Task UdpRx %p\n\r", arg);
                usleep(500*1000);
            }
            pthread_exit(NULL);
        }

        out_impl::out_impl()
        {
            pthread_t Thread_UdpRx;

            if (pthread_create(&Thread_UdpRx, NULL, task_UdpRx, NULL))
                err(1, "Pthread error");
            else
                printf("UDP thread initialization completed\n\r");
        }

        out_impl::~out_impl()
        {
        }

    }
}

编译

代码语言:javascript
复制
$ g++ --version
g++ (GCC) 4.9.0
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ make gr.o
g++ -g -O3 -std=c++11 -Wall -Wextra -Werror -c gr.cpp
$ nm -C -g gr.o
0000000000000010 T gr::adsb::task_UdpRx(void*)
0000000000000050 T gr::adsb::out_impl::out_impl()
0000000000000050 T gr::adsb::out_impl::out_impl()
0000000000000040 T gr::adsb::out_impl::~out_impl()
0000000000000000 T gr::adsb::out_impl::~out_impl()
0000000000000000 T gr::adsb::out_impl::~out_impl()
0000000000000000 V typeinfo for gr::adsb::out_impl
0000000000000000 V typeinfo name for gr::adsb::out_impl
                 U vtable for __cxxabiv1::__class_type_info
0000000000000000 V vtable for gr::adsb::out_impl
                 U operator delete(void*)
                 U err
                 U printf
                 U pthread_create
                 U usleep
$

下一步

这个问答可以从以下几个方面着手:

  1. 这个问题是被放弃或关闭的。
  2. 您可以使用MCVE代码并添加一些内容,直到获得原始编译错误为止。
  3. 你采取你的非编译代码和删除的东西,直到你到一个MCVE,你可以删除任何东西,而不删除错误。最好,代码不应该引用在常规Linux安装中找不到的任何标头。如果必须的话,你需要确定他们可以从哪里获得-是的,我可能可以找到GNU电台,如果我需要,但我不应该这样做。
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24310733

复制
相关文章

相似问题

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