クラス内関数を用いた_beginthreadex

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
みそら

クラス内関数を用いた_beginthreadex

#1

投稿記事 by みそら » 1年前

ネットで調べたのですが、どうしても分からないことがあったのでトピックを立てさせていただきました。

Windows10にてVisual Studio 2017 Communityを用いてC++でプログラミングを行っています。

タイトルの通り、以下のようなクラス内に宣言した関数(Rate())をスレッド化してRate()とCalc()のマルチスレッドを行いたいと考えております。

コード: 全て選択

class C_Calc
{
	unsigned int thID;
	HANDLE hTh;

public:
	void Calc(void);
	static void executeLauncher(void* args);
	void Rate(void);
};
それにあたり、「クラス内関数 _beginthreadex」と検索することで上位に出てきた
http://d.hatena.ne.jp/kasei_san/20070612/p1
といったサイトを参考に作ったのですが、

コード: 全て選択

hTh = (HANDLE)_beginthreadex(NULL, 0, executeLauncher, NULL, 0, &thID);
としたところ、

コード E0167
型 "int (__stdcall *)(void *args)" の引数は型 "_beginthreadex_proc_type" のパラメーターと互換性がありません

と出てきます。
この時、executeLauncherはint __stdcallにしてみたり、voidにしてみたりunsigned intにしてみたりしています。

また、

コード: 全て選択

hTh = (HANDLE)_beginthreadex(NULL, 0, &executeLauncher, NULL, 0, &thID);
と「&」をつけてみたりもしましたがダメでした。

クラス内関数Rate()をスレッド化するにはどうしたらよいのでしょうか。
ご教授いただけますと幸いです。

アバター
usao
記事: 1369
登録日時: 5年前

Re: クラス内関数を用いた_beginthreadex

#2

投稿記事 by usao » 1年前

オフトピック
参考先と同様の形で書いてみては?

かずま

Re: クラス内関数を用いた_beginthreadex

#3

投稿記事 by かずま » 1年前

void を unsigned に変更し、__stdcall を付ければコンパイルできますよ。

コード: 全て選択

#include <iostream>
#include <windows.h>  // HANDLE
#include <process.h>  // _beginthreadex

class C_Calc
{
    unsigned int thID;
    HANDLE hTh;
 
public:
    void Calc(void);
    static unsigned __stdcall executeLauncher(void* args);
    void Rate(void);

	void start() {
		hTh = (HANDLE)_beginthreadex(NULL, 0, executeLauncher, NULL, 0, &thID);
	}
};

unsigned __stdcall C_Calc::executeLauncher(void*args)
{
	for (int i = 0; i < 3; i++) {
		std::cout << "executeLauncher\n";
		Sleep(300);
	}
	_endthread();
	return 0;
}

int main()
{
	C_Calc calc;
	calc.start();
	for (int i = 0; i < 3; i++) {
		std::cout << "main\n";
		Sleep(400);
	}
}

かずま

Re: クラス内関数を用いた_beginthreadex

#4

投稿記事 by かずま » 1年前

みそら さんが書きました:クラス内関数Rate()をスレッド化するにはどうしたらよいのでしょうか。
Rate は executreLauncher から呼び出せばよいのではないでしょうか?
そのためには、_beginthreadex で、this を渡す必要があります。
また、_beginthreadex で始めたので、_endthreadex で終わるようにしてみました。

コード: 全て選択

#include <iostream>
#include <windows.h>  // HANDLE, Sleep
#include <process.h>  // _beginthreadex, _endthreadex

class C_Calc
{
    unsigned int thID;
    HANDLE hTh;
 
public:
    void Calc();
    static unsigned __stdcall executeLauncher(void *args);
    void Rate();

    void start() {
        hTh = (HANDLE)_beginthreadex(NULL, 0, executeLauncher, this, 0, &thID);
    }
};

unsigned __stdcall C_Calc::executeLauncher(void *args)
{
    C_Calc *p = reinterpret_cast<C_Calc*>(args);
    p->Rate();
    _endthreadex(0);
    return 0;
}

void C_Calc::Calc()
{
    for (int i = 0; i < 3; i++) {
        std::cout << i << ": Calc\n";
        Sleep(600);
    }
}

void C_Calc::Rate()
{
    for (int i = 0; i < 3; i++) {
        std::cout << i << ": Rate\n";
        Sleep(400);
    }
}

int main()
{
    C_Calc calc;
    calc.start();
    calc.Calc();
}

返信

“C言語何でも質問掲示板” へ戻る