クラス内関数を用いた_beginthreadex

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

クラス内関数を用いた_beginthreadex

#1

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

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

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
記事: 1889
登録日時: 12年前
連絡を取る:

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

#2

投稿記事 by usao » 8年前

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

かずま

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

#3

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

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 かずま » 8年前

みそら さんが書きました:クラス内関数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言語何でも質問掲示板” へ戻る