Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/192.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 安卓&x2B;pthread+;c++;=西格塞格夫_C++_Android_Pthreads - Fatal编程技术网

C++ 安卓&x2B;pthread+;c++;=西格塞格夫

C++ 安卓&x2B;pthread+;c++;=西格塞格夫,c++,android,pthreads,C++,Android,Pthreads,以下代码在标准linux上编译和运行: #include <iostream> #include <pthread.h> using namespace std; class Foo { public: Foo(); void go_thread(); void stop_thread(); private: static void* worker( void* param );

以下代码在标准linux上编译和运行:

#include <iostream>
#include <pthread.h>

using namespace std;

class Foo
{
    public:
        Foo();
        void go_thread();
        void stop_thread();
    private:
        static void* worker( void* param );
        pthread_t m_pt;
};

Foo::Foo()
{
    m_pt = 0;
}

void Foo::go_thread()
{
    int success = pthread_create( &m_pt, NULL, worker, static_cast<void*>(this) );

    if( success == 0 )
    {
        cout << "thread started" << endl;
    }
}

void Foo::stop_thread()
{
    int success = pthread_join( m_pt, NULL );

    if( success == 0 )
    {
        cout << "thread stopped" << endl;
    }
}

void* Foo::worker( void* p )
{
    cout << "thread running" << endl;
    return 0;
}

int main()
{
    Foo f;
    f.go_thread();
    f.stop_thread();
    return 0;
}

这段代码也使用Android NDK(r5b)构建。但是,当我将生成的可执行文件推送到一个设备并运行它时,在main()运行之前,我会得到一个SIGSEGV。我已经将这个问题隔离到
pthread_create()
似乎仅仅在我的代码中存在这个调用,更不用说执行了,就会导致我的程序出现seg错误。有什么想法吗?

可能不是这样,但请尝试让pthread调用的函数创建一个普通的c函数(即声明为extern“c”),而不是一个静态成员函数:

这是因为从技术上讲,静态成员的调用约定可能不同于C-library pthread使用的C调用约定(尽管很多时候它们是相同的(这就是为什么它可以在linux机器上工作的原因),在我看来,不值得冒移植风险)

extern“C”void*启动线程(void*);
void*启动线程(void*数据)
{
Foo*theObject=静态(数据);
//在Java中,如果您的Foo是从Runable派生的
//这是调用Object->run()的地方。
返回Foo::worker(数据);
}
int success=pthread\u create(&m\u pt,NULL,启动\u线程,静态\u强制转换(this)

问题似乎是将iostream与pthread结合起来。我用printf()s替换了所有couts,删除了using子句,并删除了iostream头。编译并运行的代码在设备上没有问题。我想知道谷歌是否应该注意到这一点

最终(工作)代码如下所示:

#include <pthread.h>
#include <stdio.h>

class Foo
{
    public:
        Foo();
        void go_thread();
        void stop_thread();
    private:
        static void* worker( void* param );
        pthread_t m_pt;
};

Foo::Foo()
{
    m_pt = 0;
}

void Foo::go_thread()
{
    int success = pthread_create( &m_pt, NULL, worker, static_cast<void*>(this) );

    if( success == 0 )
    {
        printf( "thread started\n" );
    }
}

void Foo::stop_thread()
{
    int success = pthread_join( m_pt, NULL );

    if( success == 0 )
    {
        printf( "thread stopped\n" );
    }
}

void* Foo::worker( void* p )
{
    printf( "thread running\n" );
    return 0;
}

int main()
{
    Foo f;
    f.go_thread();
    f.stop_thread();
    return 0;
}
#包括
#包括
福班
{
公众:
Foo();
void go_thread();
无效停止_螺纹();
私人:
静态void*工作者(void*参数);
pthread_t m_pt;
};
Foo::Foo()
{
m_pt=0;
}
void Foo::go_thread()
{
int success=pthread_create(&m_pt,NULL,worker,static_cast(this));
如果(成功==0)
{
printf(“线程已启动\n”);
}
}
void Foo::停止线程()
{
int success=pthread\u join(m\u pt,NULL);
如果(成功==0)
{
printf(“线程停止\n”);
}
}
void*Foo::worker(void*p)
{
printf(“线程运行\n”);
返回0;
}
int main()
{
福福;
f、 去螺纹();
f、 停止线程();
返回0;
}

您的错误检查是错误的。pthread\u create&join成功后将返回0,否则将返回一个表示错误的整数。您可能是因为某个原因而失败的,并且对此一无所知。是的,目光敏锐。我已经更正了帖子,但核心问题仍然存在。谢谢!
[basic.component]
[expr.unary.op]指向静态成员的指针可以与指向空闲函数的指针互换。这并不完全排除与 Extn“C”/Cudio>调用约定的不兼容,但您需要其他实现特定的修复来更改调用约定。@本:C++函数。不是C函数(Aka EXTENN)C”)。。注意pthread是一个C库,因此在它接收的指针上使用“C”调用约定。一旦进入start_the_thread()函数,我们当然可以正常调用静态成员函数。@Martin:正确,语言链接是函数指针类型的一部分。但它是
外部“C”的应用程序
linkage,而不是将函数移到类外,它修复了类型。由于类型不匹配,编译器应该抛出一个错误——函数指针永远不会隐式转换。@Ben:我不知道您可以应用extern“C”链接到静态成员方法。如果可以的话,这将解决问题。但我认为你不能(我可能错了),解决方案必须是将它移到类之外。这不是编译器的错误(类型是相同的(链接是它们如何调用的,而不是类型的一部分)),我从未见过编译器将此作为错误抛出,但我以前也多次看到过这个确切的问题。这是一个50/50的赌注,赌调用约定之间的性能。注意:就像80%的统计数据一样,50/50是由一个加权掷硬币组成的(让我们称之为加权掷硬币)。@Martin:你不能将
extern“C”
应用于成员函数(静态或其他)但是,如果一个自由函数是不够的,那么,如果C++函数所形成的函数指针与<代码> pthRead创建< /代码>不兼容,编译器就有义务拒绝程序。该标准不允许函数指针的隐式转换,并且这种诊断不是可选的。
extern "C" void* start_the_thread(void*);

void* start_the_thread(void* data)
{
    Foo*  theObject = static_cast<Foo*>(data);
    // In Java if your Foo had been derived from Runable
    // This is s where theObject->run() would have been called.
    return Foo::worker(data);
}

int success = pthread_create( &m_pt, NULL, start_the_thread, static_cast<void*>(this)
#include <pthread.h>
#include <stdio.h>

class Foo
{
    public:
        Foo();
        void go_thread();
        void stop_thread();
    private:
        static void* worker( void* param );
        pthread_t m_pt;
};

Foo::Foo()
{
    m_pt = 0;
}

void Foo::go_thread()
{
    int success = pthread_create( &m_pt, NULL, worker, static_cast<void*>(this) );

    if( success == 0 )
    {
        printf( "thread started\n" );
    }
}

void Foo::stop_thread()
{
    int success = pthread_join( m_pt, NULL );

    if( success == 0 )
    {
        printf( "thread stopped\n" );
    }
}

void* Foo::worker( void* p )
{
    printf( "thread running\n" );
    return 0;
}

int main()
{
    Foo f;
    f.go_thread();
    f.stop_thread();
    return 0;
}