C++ C++;:在类中使用静态函数从main创建pthread时,Solaris Studio中出现警告(计时错误)

C++ C++;:在类中使用静态函数从main创建pthread时,Solaris Studio中出现警告(计时错误),c++,pthreads,solaris,C++,Pthreads,Solaris,我一直面临着这个警告 我有一个主C++程序,它创建了几个线程。这些线程运行特定类中的函数。为了做到这一点,这个类有一个静态函数,它返回我在这些线程中运行的实际函数。我将粘贴代码的相关部分,以便您更好地理解 以下是Car.h的相关部分,该类的头函数在线程中运行: [...] class Car { public: [...] void *GoForward(void); //Runs in the thread static void* G

我一直面临着这个警告

<>我有一个主C++程序,它创建了几个线程。这些线程运行特定类中的函数。为了做到这一点,这个类有一个静态函数,它返回我在这些线程中运行的实际函数。我将粘贴代码的相关部分,以便您更好地理解

以下是Car.h的相关部分,该类的头函数在线程中运行:

[...]
class Car {

public:
    [...]
    void *GoForward(void);                 //Runs in the thread
    static void* GoForward_helper(void *); //Sends the previous one to the thread
    [...]
[...]
vector<Car *> cars;    //Pointers to objects whose functions I want to run in threads
int threadsLaunched = 0;
pthread_t threads[numberOfThreads]; 
vector<int> freeSlots; //The number of threads is limited
[...]          
int slot = freeSlots.at(0);
threadCode = pthread_create(&threads[slot], NULL, 
                    &Car::GoForward_helper, 
                    new ThreadParameters(cars.at(threadsLaunched), slot));
这是Car.cpp中作为参数传递给pthread_create的函数,它返回在线程中实际运行的函数。这是我发现的在线程中运行不同类函数的唯一方法:

[...]
void *Car::GoForward_helper(void *context) {

    //Just getting parameters, not big deal
    ThreadParameters* parameters = (ThreadParameters*) context;
    int newSlot = parameters->GetSlot();
    parameters->GetCar()->setSlot(newSlot);

    //Returns the function I want to run in the thread
    return parameters->GetCar()->GoForward();
}
[...]
void* Car::GoForward(void) {
    //Tasks which actually run in the thread
}
[...]
这些是发送到helper函数的参数。没有相关内容,我粘贴它们是为了方便您:

[...]
class ThreadParameters {
public:
    ThreadParameters(Car*, int);
    Car* GetCar();
    int GetSlot();
    [...]
private:
    Car* context;
    int slot;
[...]
…最后,这是main()中创建线程的代码:

[...]
class Car {

public:
    [...]
    void *GoForward(void);                 //Runs in the thread
    static void* GoForward_helper(void *); //Sends the previous one to the thread
    [...]
[...]
vector<Car *> cars;    //Pointers to objects whose functions I want to run in threads
int threadsLaunched = 0;
pthread_t threads[numberOfThreads]; 
vector<int> freeSlots; //The number of threads is limited
[...]          
int slot = freeSlots.at(0);
threadCode = pthread_create(&threads[slot], NULL, 
                    &Car::GoForward_helper, 
                    new ThreadParameters(cars.at(threadsLaunched), slot));
[…]
矢量汽车//指向要在线程中运行其函数的对象的指针
int threadsLaunched=0;
pthread_t threads[线程数];
矢量自由区//线程的数量是有限的
[...]          
int插槽=自由插槽。在(0)处;
threadCode=pthread\u创建(&threads[slot],NULL,
&汽车:GoForward_helper,
新的螺纹参数(cars.at(螺纹未固定),槽);
我正在Solaris 10中使用Oracle Solaris Studio 12.3对其进行编程。在构建项目时,我得到了与main()中创建线程的行对应的警告:

“main.cpp”,第80行:警告(不合时宜):类型的形式参数3 调用pthread_create(unsigned*,const)时的外部“C”void*()(void) _pthread_attr*,外部“C”void*()(void),void*)正在被传递void*()(void)


代码工作起来很有魅力,但我在编译时仍然收到这个警告,老实说,我讨厌没有一个完全干净的编译过程。我已经找到了几十个使用extern“C”的解决方案,但是这些解决方案都与我的代码结构不匹配,因此没有一个适合我,我希望消除任何警告(解决它们,而不是隐藏它们)。

您收到警告是因为
pthread\u create()
需要一个指向具有
C++语言链接的函数的指针
,但您正在传递它
Car::GoForward\u helper
,它具有
C++语言链接
。虽然在实践中这很可能会起作用,但这两者实际上是不同的;例如,C和C++链接函数可以使用不同的调用约定。

不可否认,类成员(甚至是静态成员)除了C++之外,还不能有语言链接。换句话说,严格按照规则的字面意思,在需要C函数的地方,不可能使用静态成员函数作为回调函数

要解决此问题,必须使助手成为一个自由函数,并为其提供C语言链接:

[...]
class Car {

public:
    [...]
    void *GoForward(void);                 //Runs in the thread
    [...]
};

extern "C" void* GoForward_helper(void *); //Sends GoForward() to the thread
实施方式如下:

extern "C" void *GoForward_helper(void *context) {

    //Just getting parameters, not big deal
    ThreadParameters* parameters = (ThreadParameters*) context;
    int newSlot = parameters->GetSlot();
    parameters->GetCar()->setSlot(newSlot);

    //Returns the function I want to run in the thread
    return parameters->GetCar()->GoForward();
}
extern "C" void* GoForward_helper_C(void *arg) {
  return Car::GoForward_helper(arg);
}

另外一个选项,特别是当函数需要类似成员的访问时,您可以保留静态选项并简单地委托给它:

[...]
class Car {

public:
    [...]
    void *GoForward(void);                 //Runs in the thread
    static void* GoForward_helper(void *); //Sends the previous one to the thread
    [...]
};

extern "C" void* GoForward_helper_C(void *);
实施方式如下:

extern "C" void *GoForward_helper(void *context) {

    //Just getting parameters, not big deal
    ThreadParameters* parameters = (ThreadParameters*) context;
    int newSlot = parameters->GetSlot();
    parameters->GetCar()->setSlot(newSlot);

    //Returns the function I want to run in the thread
    return parameters->GetCar()->GoForward();
}
extern "C" void* GoForward_helper_C(void *arg) {
  return Car::GoForward_helper(arg);
}

嗨,安吉。感谢您的回复,并对延误表示歉意。你的代码正是我要找的。再次感谢你。