开启线程
头文件中,定义一个 MyFFmpeg 类:
class MyFFmpeg {
public:
MyFFmpeg(JavaCallHelper *javaCallHelper, const char *dataSource);
~MyFFmpeg();
private:
pthread_t pid_prepare;// FFmpeg初始化线程
char *url;// 播放地址
JavaCallHelper *pJavaCallHelper;// 回调Java层的接口
void *prepareFFmpeg(void *args);// 线程函数
};
实现类中,开启线程的代码:
/**
* 被子线程调用的指针函数
*/
void *MyFFmpeg::prepareFFmpeg(void *args) {
...省略
return nullptr;
}
void MyFFmpeg::prepare() {
// 参数1:线程id
// 参数2:线程的属性,nullptr 默认属性
// 参数3:线程创建之后执行的函数,函数指针
// 参数4:参数3函数接受的参数
pthread_create(&pid_prepare, nullptr, prepareFFmpeg, nullptr);
}
上面这种的写法,在编译时期就会报错,错误日志:
error: reference to non-static member function must be called
pthread_create(&pid_prepare, nullptr, prepareFFmpeg, nullptr);
^~~~~~~~~~~~~
解决方式
error: reference to non-static member function must be called
这个日志的大概意思是:你引用(调用)了非静态函数。
方式一:
按照错误提示,将 prepareFFmpeg
定义为静态函数即可解决该问题。
class MyFFmpeg {
public:
MyFFmpeg(JavaCallHelper *javaCallHelper, const char *dataSource);
~MyFFmpeg();
private:
pthread_t pid_prepare;// FFmpeg初始化线程
char *url;// 播放地址
JavaCallHelper *pJavaCallHelper;// 回调Java层的接口
static void *prepareFFmpeg(void *args);// 线程函数
};
但是存在一个问题,静态函数不能访问非静态成员,我需要在 prepareFFmpeg
函数中访问 MyFFmpeg 中的非静态成员,如果全部改为静态,很不优雅,所以推荐使用方式二。
方式二:
- 头文件中,在 MyFFmpeg 类内部创建新的成员函数
prepareFFmpeg
。
这样的优势在于,可以方便的使用 MyFFmpeg 的成员变量。
class MyFFmpeg {
public:
MyFFmpeg(JavaCallHelper *javaCallHelper, const char *dataSource);
~MyFFmpeg();
void prepareFFmpeg();
private:
pthread_t pid_prepare;// FFmpeg初始化线程
char *url;// 播放地址
JavaCallHelper *pJavaCallHelper;// 回调Java层的接口
};
- 实现类中,
prepareFFmpeg
内部的逻辑还是之前的内容。
void MyFFmpeg::prepareFFmpeg() {
...省略
}
- 实现类中,将原先的
prepareFFmpeg
封装为全局函数prepareFFmpeg_
,提供给线程调用。
/**
* 被子线程调用的指针函数
*/
void *prepareFFmpeg_(void *args) {
auto *pFFmpeg = static_cast<MyFFmpeg *>(args);
// 内部调用MyFFmpeg的成员函数
pFFmpeg->prepareFFmpeg();
return nullptr;
}
- 实现类中,开启线程。
void MyFFmpeg::prepare() {
// 最后参数
pthread_create(&pid_prepare, nullptr, prepareFFmpeg_, this);
}
完成,解决问题!
网友评论