• ベストアンサー

こんなコンパイルエラーがでます。

OS:WinNT4.0 環境:VC++6.0 MFC コンパイル時に次のエラーが出て来ました。 error C2664: 'qsort' : 4 番目の引数を 'int (const void *,const void *)' から 'int (__cdecl *)(const void *,const void *)' に変換できません。 (新しい機能 ; ヘルプを参照)スコープ内でこの名前を持つ関数でターゲット型に一致するものはありません。 qsort関数の引数関数を'int xxxxxxx(const void *,const void *)に宣言したところこのエラーが出てきました。 何がなんだかさっぱりわかりません。 ぜひお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • leaz024
  • ベストアンサー率75% (398/526)
回答No.3

 まず、CとC++では動作のメカニズムが異なるため、Cでコンパイルされた関数をC++から呼び出す場合には、その旨をC++コンパイラに指示する必要があります。  qsort関数はCのライブラリ関数であり、qsortが内部から呼び出す比較関数もCでコンパイルされたものでなければなりません。  ところが比較関数はC++ソース内に記述され、C++としてコンパイルされるため、qsortからは呼び出せないというエラーが出ているのです。  一体何がそんなに違うのかというと、内部的な関数名や、引数の処理の仕方(スタックのクリア方法)などが大きく異なるのです。これを指定するのが「関数呼び出し規約」と言われるものです。ちなみにCにはありません。  C++内でのCの呼び出し規約は「__cdecl(C default callの略)」というキーワードで表されます。異なる呼び出し規約への変換は出来ないため、質問のようなエラーが出たのでしょうね。  確かに比較関数に__cdeclをつけて宣言すれば直ると思いますが、普通は「リンケージ指定」を使って、   extern "C" int comp(const void *a, const void *b);   extern "C"   {     int comp(const void *a, const void *b)     {       // コード     }   } のように書いて、そこだけCとしてコンパイルします。  また比較関数に関するコードだけ、.cのファイルに記述しても同様の効果があります。  __cdeclなどは推奨されたキーワードではないため、自分ではなるべく使わない方が良いでしょう。

その他の回答 (2)

  • itohh
  • ベストアンサー率45% (210/459)
回答No.2

こんにちは。itohhといいます。 qsort関数は、メンバ関数として定義しては行けません。 静的関数として定義しましょう。 例. void CTest::m_qsort() { qsort(buf, num, len, ::xxxxxx ); } static int __cdecl xxxxxx(LPCVOID a, LPCVOID b) { }

  • haru-p
  • ベストアンサー率28% (34/119)
回答No.1

こんにちは。 エラーメッセージ内に (__cdecl *) がありますよね。 これは関数の呼び出し規約が __cdecl ですよーと言う意味です。 VC++6.0 でプロジェクトを作るとデフォルトの呼び出し規約が __cdecl になっていて問題なくビルドが通ると思いますが、 呼び出し規約を変えませんでした? 呼び出し規約の変更はメニューから、 プロジェクト(P)→設定(S)→C/C++タブ→カテゴリ[コード生成] にあります。 確認してみて下さい。