2017-10-03 1 views
0

OpenGLのデバッグについて学ぶとき、何か問題が発生したときにOpenGL APIからデバッグエラーメッセージを受け取る関数コールバックを実装しました。チュートリアルでは、関数シグネチャは次のようになっています。この関数の先頭に__stdcallを付ける必要がありますか?

typedef void APIENTRY funcname(GLenum source​, GLenum type​, GLuint id​, 
    GLenum severity​, GLsizei length​, const GLchar* message​, const void* userParam​); 

Windowsではこのコールバックを実装しました。 Windowsでは、APIENTRYは__stdcallの定義です。 __stdcall私は、呼び出し規約を指定するWindows固有のキーワードと考えています。後で私は自分のコードをLinuxに移植しました。そして、まずは、GCCとEclipseの間では、Windows定義のため、APIENTRYを認識しませんでした。私のコールバック関数として「glCheckError_前に期待される初期化子」

です

:だから私は、私はそれが認識するかどうか分からないこれ、__stdcallするためにそれを変更しましたが、関係なく、それはというエラーを投げましたvoid __stdcall glCheckError _(/ Params /)。 __stdcall序文を削除すると、プログラムがうまく動作します。

WindowsまたはLinuxの場合、この接頭辞が必要かどうかは疑問です。面白いのは、関数シグネチャに__stdcallを追加することを提案した場所は、OpenGLのドキュメントを保持するKhronosのWebページだったから、OS固有の情報を指定してはならない限り、OpenGLは、プラットフォーム。だから私はこの__stdcallプレフィックスが必要ですか?

+0

このキーワードはVisual C++固有のものです – Asesh

+0

APIENTRYと__stdcallの両方ですか?私はそれがOpenGLのドキュメントは、このようにコールバックを行うために言及して奇妙なことがわかります。 Windows固有のチュートリアルではないためです。 – Zebrafish

+1

APIENTRYは__stdcallとして定義されています – Asesh

答えて

1

Windowsでは、32ビット未満の場合のみ、違いがあります。 (デフォルトは__cdecl呼び出し規約、v.s.はOpenGLで使用される__stdcallです)。間違った規約を使用すると、スタックが壊れてしまうことがあります(コンパイラは不運にもエラーになります)。

64ビットウィンドウでは違いはありません(stdcallは使用できないため、すべての__stdcall/__ cdeclはデフォルトで__fastcallになります)。

linux/macos/android/iosと違いはありません。

これをマクロで囲むことが必要です。

#if definded(_WIN32) && !defined(_WIN64) 
# define STDCALL __stdcall 
#else 
# define STDCALL 
#endif 
+0

これは非常に役に立ちます。 SOの呼び出し規約の違いについては、この32ビットと64ビットのビジネスは言及されませんでした。ありがとう。 – Zebrafish

+0

うん。64ビットのウィンドウでは、 __fastcallまたは__vectorcallの2つのオプションがあります。ここで、__vectorcallは、浮動小数点/ベクトル引数を渡すとき(スタックに戻るのではなく)にさらに多くのレジスタを使用します。 Linux/BSD/Macosはすべて__vectorcallのみを使用します(どの汎用レジスタが使用されているかは実際の問題とは少し異なります)。 他の唯一の選択肢は 'extern' C '' ' (C++ネームマングリングを無効にする)、またはextern C(C++ネームマングリングを有効にする)にしないでください。 – robthebloke

関連する問題