現在マルチスレッドアプリケーションを作成しています。
ところが、
CreateThread(NULL, 0, listenThread, this, 0, &m_listenThreadId);
この行でエラーが出ます。
エラー内容は、
3番目の引数を'unsigned long (void *)' から 'unsigned long (__stdcall *)(void *)' に変換できません。
です。関数のポインタについてもまだよく理解していないので、このエラーの意味が良く分かりません。
どなたか、エラーの意味と解決方法を教えて頂けませんか?
コンパイラはVisual C++6.0です。
どうぞ宜しくお願いします。

このQ&Aに関連する最新のQ&A

A 回答 (4件)

解決方法は他の方が示されているので、私はstdcallの事を説明します。



関数や他の言語のプロシージャ、サブルーチンなどは名前付け規約と呼び出し規約が規格上決まっています。

Visual C++ではデフォルトの規約は_cdeclであり、規約では引数を右から左に向かってスタックに積み、つんだスタックの破棄は呼び出し側で行います。
それに対して_stdcallでは呼び出し順序こそ同じですが、スタックの破棄は呼び出された側が処理する事になっています(よってykkw_2001さんの示された方法でやった場合、コンパイルは通るでしょうがスタックの整合性が保てない事になるため危険です)。

なぜこのような規約になっているかは私も不勉強のため知らないのですが、_cdecl規約の利点として可変個の引数の関数を作る事が出来る、という事です。
たとえば入門用によく使われるprintf()関数などは第一引数のchar*の内容を解析して引数の個数を調べ、その数から判断してスタックから引数を自分で取ってくるようになっています(当然積んだ個数<パラメータの数の場合、ヤバイ事になります(^^;)。
んじゃ、なぜ_stdcallがあるのか?というのはx86系CPU(互換含む)では
RET n
(nは即値、プログラムコード上で既に決まっている定数の事)
という命令があり、関数から戻るときに同時にスタックに積まれた引数を始末する事が出来るためです。
_cdeclではRET命令で戻ってきた後に呼び出し側が破棄する(といってもスタックポインタの操作だけですが)ため、速度は微妙に_stdcallのほうが早くなります。
そのため頻繁に呼び出されるWin32APIは一つのAPIを除いてすべて_stdcallで宣言されています(問題の一つはwsprintf関数です。MSDNの解説を見てみてください)。

実際には上記の呼び出し規約だけではなく、名前付け規約の方もかかってくる場合があります(CとC++を併用する場合とか)。そのへんは参考URLかMSDNを参照してください。

Helpに載っている事なので釈迦に説法かもしれませんが・・・
CreateThread APIでは標準C関数の初期化処理について問題が発生するため引数に渡す関数とそこから呼ばれる関数に標準C関数が無い事を確認してください。でないとメモリリークが発生します。
標準C関数を使いたい場合は_beginthread(), _beginthreadex()関数、 またはMFCのCWinThreadクラスをお使いください。

参考URL:http://www.microsoft.com/japan/developer/library …
    • good
    • 0

MFCを使っていいのなら、


-------------------------------------
CWinThread *pThread = AfxBeginThread(
listenThread,
this);
-------------------------------------
で、スレッド作成したほうが簡単ですよ。
(listenThreadは、自作関数)
    • good
    • 0

CreateThreadの3番目のパラメータは、


 DWORD WINAPI ThreadFunc(LPVOID t) {}
これと同様の関数のアドレスを必要とします。

というエラーです。WINAPIを付けていないのが原因だと思います。

余談ですが、関数(へ)のポインタと言うと、
void (PointerToFunction*)(int, int);
などの、関数のアドレスを入れる変数を意味します。変数そのものがポインタで、その値はアドレスです。
    • good
    • 0

CreateThread(NULL, 0, (unsigned long (__stdcall *)(void *))listenThread, this, 0, &m_listenThreadId);



じゃだめ?
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q【VB2005】ヘルプの使い方

お世話になります。

Visual Basic 2005のヘルプの使い方について質問です。
----------------------------------------------------------------
(1)ダイナミックヘルプが表示されない。
 例:Stringを選択している状態で、「現在の選択範囲で使用できる
リンクはありません」と表示される。)

(2)キーワード検索を行うため、文字を入力したのですが検索候補が
表示されない。それ伴い、キーワード検索結果と目次の同期がと
れない。フィルタ条件が選択できない。(リストがない)
例:キーワードに「AppendTextメソッド」と入力しても検索候補
のカーソルが「移動」へ行き、その状態から変わらない。

(3)MSDNライブラリのコラムや記事が存在しない。
----------------------------------------------------------------
(1)~(3)までを表示(利用)できるようにしたいのですが、
どうすればよろしいでしょうか?

お手数ですが、ヘルプのヘルプをお願い致します。<(_ _)>

お世話になります。

Visual Basic 2005のヘルプの使い方について質問です。
----------------------------------------------------------------
(1)ダイナミックヘルプが表示されない。
 例:Stringを選択している状態で、「現在の選択範囲で使用できる
リンクはありません」と表示される。)

(2)キーワード検索を行うため、文字を入力したのですが検索候補が
表示されない。それ伴い、キーワード検索結果と目次の同期がと
れない。フィルタ条件が選択できない。(リストがない)
例:...続きを読む

Aベストアンサー

> Expressです。
ダウンロード版ですか?

> …特に何もしていないのです…。;
> インストールするにはどうしたらよいでしょうか?

Expressのダウンロード版のMSDNライブラリは、
本体とは別にダウンロードし無くてはならなかったはずです。

で、MSのサイトを見てみましたが・・・
現在VB2008が出た所為で、ダウンロードページが変わってしまっていて、
「Expressのダウンロード版のMSDNライブラリ」のダウンロードへのリンクがなくなってしまったみたいです。
(http://www.microsoft.com/japan/msdn/vstudio/express/past/2005/)

ただ、Googleのキャッシュに残っているようです。

(http://209.85.175.104/search?q=cache:cohXeYOm9lgJ:thesource.ofallevil.com/japan/msdn/vstudio/express/vbasic/+%E8%BF%BD%E5%8A%A0%E3%81%AE%E8%A3%BD%E5%93%81%E3%83%89%E3%82%AD%E3%83%A5%E3%83%A1%E3%83%B3%E3%83%88%E3%82%92%E5%8F%82%E7%85%A7%E3%81%99%E3%82%8B%E5%A0%B4%E5%90%88&hl=ja&ct=clnk&cd=1&gl=jp)

この「追加の製品ドキュメントを参照する場合は、MSDN Express Library をインストールしてください 」
のリンクからダウンロードしてみてください。

> Expressです。
ダウンロード版ですか?

> …特に何もしていないのです…。;
> インストールするにはどうしたらよいでしょうか?

Expressのダウンロード版のMSDNライブラリは、
本体とは別にダウンロードし無くてはならなかったはずです。

で、MSのサイトを見てみましたが・・・
現在VB2008が出た所為で、ダウンロードページが変わってしまっていて、
「Expressのダウンロード版のMSDNライブラリ」のダウンロードへのリンクがなくなってしまったみたいです。
(http://www.microsoft.com/japan/msd...続きを読む

Qエラー「invalid conversion from `void (*)()' to `void (*)(int)'」

皆様、よろしくお願いしたします。RedHat9上で
次のような「鬼ごっこのプログラム」server.cをコンパイルしています。

$ g++ -o server server.c
server.c: function 内の `void session_init(int, char, int, int, char, int,
int)':
server.c:134: invalid conversion from `void (*)()' to `void (*)(int)'

というエラーが出てしまいます。
134行というと
「 signal(SIGINT, die);」
なのですが何が間違っているんでしょうか?

Aベストアンサー

die の宣言を
void die(int sig);
にしたのであれば, session_loop の中で die を呼出すときにも引数は必要ですよ.

また, 最後の die の定義のところでも引数を取るようにしていますよね? ←念の為.

QC++.NET の String型の使い方

初めて質問いたします。
C++ .NET 2005 Express Beta版を入手し、Windows Formsのプログラミングを勉強してます。

TextBoxのTextに値を変数で指定したいのですがどうすれば良いのかわかりません。

  textBox1->Text = "Test";
とダイレクトに値を指定すればできるのですが、

  #include <string>
  using namespace std;
   (省略)
  string str = "Test";
  textBox1->Text = str;
は、エラーになってしまいます。

C++標準のstringクラスではなく、.NETはStringクラスがあるようですが、これの使い方がMSDN等で調べているのですが分かりません。
分かりやすいURLなどありましたら教えていただけませんか。

Aベストアンサー

textBox1->Text = new String(str.c_str());
でいけるんじゃないかなあ。
試してないのでなんですが、
C++のstringクラスからは、c_str()で、いわゆるNULL終端文字列へのポインタが得られて
.NETのStringクラスは、NULL終端文字列でのコンストラクタがありますから。

Qilink32について。'__setargv__'と'__turboFloat__'が未解決

WindowsXP+bcc32+ilink32でGLUTを使ったプログラムを書いています。
bccの設定はsetbcc.exe(http://www.cmagazine.jp/setbcc.html)を使いました。
opengl32.lib, glu32.lib, glut32.libはimplib.exe(http://blog.jyoken.net/?eid=478291)を使って作成しました。

以上の設定でbcc32付属のMakeを使ってmakeしたところ、
コンパイル後のリンクで以下のようなエラーが出てしまい困っています。
どなたか解決法を教えていただけないでしょうか?

よろしくお願いします。


---------------------
エラーの内容
---------------------
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland
Error: 外部シンボル '__setargv__' が未解決(root が参照)
Error: 外部シンボル '__turboFloat' が未解決(root が参照)
---------------------

---------------------
使用しているMakefile
---------------------
CC= bcc32
LINKER= ilink32

SRCS= main.c callback.c Task.c Logger.c
OBJS= $(SRCS:.c=.obj)
TARGET= main.exe

CFLAGS= -wall -O2
LFLAGS=
LIBS= opengl32.lib glu32.lib glut32.lib

INCLUDE= -I"C:\borland\bcc55\Include"
LIB= -L"C:\borland\bcc55\Lib"


all: $(TARGET)

.SUFFIXES : .obj .c

.c.obj:
$(CC) $(CFLAGS) -c $(SRCS)

$(TARGET): $(OBJS)
$(LINKER) $(LFLAGS) $(LIB) $(OBJS),$(TARGET),,$(LIBS)
---------------------

WindowsXP+bcc32+ilink32でGLUTを使ったプログラムを書いています。
bccの設定はsetbcc.exe(http://www.cmagazine.jp/setbcc.html)を使いました。
opengl32.lib, glu32.lib, glut32.libはimplib.exe(http://blog.jyoken.net/?eid=478291)を使って作成しました。

以上の設定でbcc32付属のMakeを使ってmakeしたところ、
コンパイル後のリンクで以下のようなエラーが出てしまい困っています。
どなたか解決法を教えていただけないでしょうか?

よろしくお願いします。


---------------------
エラー...続きを読む

Aベストアンサー

BorlandのCコンパイラは、スタートアップルーチンを含むオブジェクトファイルは
ライブラリファイルの中にはアーカイブされていなくて、適切な
スタートアップ用.objファイルを別途指定してリンクしていたと思います
#bcc32.exeを使った場合はコンパイラドライバが自動でやってくれる。

質問にあるMakefileの内容を見た感じでは、そのOBJファイルを指定していませんので、
それが原因で解決できないシンボル名がでているのだと思います。
ということで、ilink32.exeでリンクする対象にそのスタートアップ用OBJファイルを
含めてやればよろしいかと。

C0なんとか.OBJという名前で、コンパイルオプションに応じていくつか
存在していたと思います。
#置かれている場所はライブラリファイルのあるディレクトリです。

Qカッコ悪い使い方

カッコ悪い使い方ってあると思います。
モノの使い方、言葉の使い方、ファッション、
店の利用の仕方、あるいは、このサイトやネットの使い方etc
皆さんの考える「この使い方はカッコ悪い」を教えて下さい。

Aベストアンサー

ものの使い方ではないんですが、ひとつ挙げるとすれば、その人が外見的にカッコ良い人でもそうでなくても、いかにもカッコつけた態度をとっている人、つまり自意識過剰が見え見えの人はカッコ悪いと思います。

逆に言えば、自分に自信が持てるってことは、すごく幸せなことかも。
ま、それがその人の性格だったら、どうしようもないですけど・・・(-_-;)

Qc 文字列の終わりを示すコードは 0x00 それとも '?0' , '/0' ?

cの本を参考にプログラムをかじっているのですが、
本には '?0' と書いてあり、それで出力してみるとうまくいかず
いろいろインターネットで調べたのですが、
0x00 だとうまくいきました。
良くわからないのですが、なぜでしょう?

スミマセンおねがいします。

Aベストアンサー

文字列の最後には'\0'(NULL)が必要になります。
0x00で上手くいったのは、
NULLも「整数値の0」だからです。

Qラブホテルで、本来以外の使い方をした経験、ありますか?

本来の使い方は、皆さん知っていますね?
そうではなくて、本来以外の使い方です。
テレビで「ラブホ女子会」が流行っている話をしていましたが、例えばそういうこととか、単に寝るために泊まったとか、出張で使ったとか、カラオケとか、昼寝とか・・・とにかく、本来の使い方ではない使い方です。
もちろんその後も、本来の使い方はしないでチェックアウトしたという前提です。

ラブホテルによっては、そういう使い方を認めないところもあるようですが、本来以外の使い方をした経験はありますか?

Aベストアンサー

お盆に家族旅行に行ったとき高速で30Km渋滞と表示されていたので、雄琴温泉に仕方なく宿泊しようとした。何処も満室で仕方なくラブホに家族で宿泊した。
回転するベッドや明るさの調整できる風呂があり、子供が大はしゃぎで遊んでいた。
妻とこんな使い方もあるなーと話をした。家族全員だと雄琴なら6,7万円必要なところ8000円ですみ
朝食もディナーのような肉料理だった。フロントの人は、普通はこんな使い方しないけど、いい勉強になった
こんな使い方も考えてみたいと言っていた。

Q「void ( *signal(int sig, void (*func)(int)) ) (int)」の (int)

signal関数の書式についてですが、

  void ( *signal(int sig, void (*func)(int)) ) (int);

最後に付く(int)は一体何でしょうか?
このような関数の書式ははじめて見ました。
UNIX系の何かでしょうか。
回答よろしくお願いします。

Aベストアンサー

typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t sighandler);
より後半部分のtypedefを置き換えると
sighandler_t signal(int signum, void (*sighandler)(int));
つぎに戻り値の部分のtypedefを置き換えると
void (*signal(int signum, void (*sighandler)(int)))(int);
となります。
(
sighandler_t signal(int signum, void (*sighandler)(int));
の「signal(int signum, void (*sighandler)(int))」をAと置き換えて
sighandler_t A;
からtypedefを置き換えると
void (*A)(int);
となり、Aを戻すと
void (*signal(int signum, void (*sighandler)(int)))(int);
となる。
)

typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t sighandler);
より後半部分のtypedefを置き換えると
sighandler_t signal(int signum, void (*sighandler)(int));
つぎに戻り値の部分のtypedefを置き換えると
void (*signal(int signum, void (*sighandler)(int)))(int);
となります。
(
sighandler_t signal(int signum, void (*sighandler)(int));
の「signal(int signum, void (*sighandler)(int))」をAと置き換えて
sighandler_t A;
からtypedefを置き換...続きを読む

Qこのお箸の使い方ってOKなんですか?はたして疑問

たまに目にする箸の使い方。
フォークとナイフのように右と左に1本づつ持って
何かを切る、という箸の使い方って正しいんでしょうか。
私個人的にはそういう使い方を目にすると
嫌悪感を覚えるのですが。以前テレビを見ていたとき
君島十和子さんが堂々とそういう使い方をするのを
見て驚きました。ネットで調べたけれど、この使い方に
ついては見つけることができませんでした。
どなたか教えてください。

Aベストアンサー

調べてきました。
「ちぎり箸」というそうで、間違った使い方のひとつとのことです。

参考URL:http://www.table-manners.org/dainty_kaiseki/chopsticks/

Qvoid (*signal(int signum, void (*handler)(int)))(int);

の解釈を教えてください
最後の「(int)」については詳しくお願いします

Aベストアンサー

signalが

(1)1つ目の引数の型:int
(2)2つ目の引数の型:引数がintで戻り値がvoidである関数へのポインタ
(3)戻り値の型:引数がintで戻り値がvoidである関数へのポインタ(2と同じ)

を満たす関数である事を宣言しています。最後の(int)はsignalの戻り値の
関数ポインタがint型の引数を持つ事を示しています。

「引数がintで戻り値がvoidである関数へのポインタ」の型をHANDLERと表すと

HANDLER signal(int signum, HANDLER handler);

となります。


人気Q&Aランキング