0

私は現在、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))

誰にもアイデアはありますか?

必要に応じて、詳細をお尋ねください。私が表示したコードは、可能な限り最高の理解を得るために私ができる最短のものです.

ありがとうございました !

4

1 に答える 1

2

メンバ関数へのポインタを に渡すことはできません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 ではありません。コピーしてコンパイルすることはできません。多くのヘッダーが欠落しています。タイプoutout_implは定義/宣言されていません。GNU Radio の継承の一部は、おそらく省略される可能性があります。

これが私のバージョンの MCVE です。問題を再現しないため、完全ではありません。GCC 4.9.0 を使用する Ubuntu 12.04 LTS 派生物でクリーンにコンパイルされます。<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&A には、いくつかの方法があります。

  1. 質問は放棄またはクローズされています。
  2. 元のコンパイル エラーが発生するまで、MCVE コードを取得して追加し直します。
  3. エラーを削除せずに何も削除できないMCVEに到達するまで、非コンパイルコードを取得して削除します。できれば、通常の Linux インストールでは見つからないヘッダーをコードで参照しないでください。もしそうしなければならないのであれば、それらがどこから入手できるかを特定する必要があります — はい、必要に応じておそらく GNU Radio を見つけることができますが、そうする必要はないはずです。
于 2014-06-19T16:15:07.697 に答える