аргумент типа ‘void * (…) (void *)’ не соответствует ‘void * (*) (void *)

В настоящее время я занимаюсь разработкой блока на GNU Radio и хочу использовать тему. Этот поток предназначен для получения данных из сокета UDP, поэтому я могу использовать его в своем блоке GNU Radio. Функция «общая работа» — это та, которая выполняет всю обработку сигналов и данных.

Основной исходный файл организован так:

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 */`

Проблема, которую я получаю, состоит в том, что, когда я пытаюсь скомпилировать, я получаю эту ошибку:

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:

if(pthread_create(&Thread_UdpRx, NULL, task_UdpRx, NULL))

У кого-нибудь есть идеи?

Не стесняйтесь спрашивать более подробную информацию, если это необходимо. Код, который я показал, является самым коротким, что я мог сделать, чтобы вы получили лучшее понимание.

Спасибо !

0

Решение

Вы не можете передать указатель на функцию-член pthread_create(),

Вам понадобится бесплатная функция:

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 указатель в качестве аргумента данных:

if (pthread_create(&Thread_UdpRx, NULL, thread_start, this))

Я оставляю за собой право злоупотреблять reinterpret_cast<>() — заменить правильную нотацию. У меня есть сомнения по поводу запуска потока в конструкторе, но это схема схемы, которая должна работать.


После обновления кода на 2014-06-25

Код все еще не MCVE. Я не могу скопировать его и скомпилировать. Отсутствует много заголовков. Типы out а также out_impl не определены / объявлены. Некоторые вещи, связанные с наследованием GNU Radio, вероятно, могут быть опущены.

Вот моя версия MCVE. Это не идеально, потому что это не воспроизводит вашу проблему. Он аккуратно компилируется на производной Ubuntu 12.04 LTS с GCC 4.9.0. Предполагается, что у вас есть заголовок <err.h> который определяет функцию err(), Я не уверен, что деструктор необходим для MCVE (и удаление его устранит еще 5 строк или около того).

Источник

#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()
{
}

}
}

компиляция

$ 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
$

Следующие шаги

Есть несколько способов, которыми этот Q&А может пойти отсюда:

  1. Вопрос оставлен или закрыт.
  2. Вы берете код MCVE и добавляете обратно, пока не получите исходную ошибку компиляции.
  3. Вы берете свой некомпилируемый код и удаляете вещи, пока не доберетесь до MCVE, из которого ничего не можете удалить, не удаляя ошибку. Предпочтительно код не должен ссылаться на какие-либо заголовки, которые не найдены в обычной установке Linux. Если это необходимо, вам нужно определить, откуда они доступны — да, я, вероятно, смогу найти GNU Radio, если мне нужно, но мне не нужно это делать.
2

Другие решения


По вопросам рекламы [email protected]