C++ 安卓&x2B;pthread+;c++;=西格塞格夫
以下代码在标准linux上编译和运行: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 );
#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;
}