2012-05-01 10 views
1

が行くで書かれたこの超シンプルな小さなテスト・ケースのOpenGLのプログラムを見てみましょ原因:のOpenGLのにglClear()は、Windows 64でのアクセス違反(0xc0000005)に

package main 

import (
    "runtime" 
    "./glfw" 
    gl "github.com/chsc/gogl/gl21" 
) 

func onExit (err error) { 
    glfw.Terminate() 
    if err != nil { panic(err) } 
} 

func main() { 
    runtime.LockOSThread() 
    err := glfw.Init() 
    if err != nil { panic(err) } 
    err = glfw.OpenWindow(1280, 720, 0, 0, 0, 0, 0, 0, glfw.Windowed) 
    if err != nil { onExit(err) } 
    err = gl.Init() 
    if err != nil || gl.GetError() != 0 { onExit(err) } 
    for glfw.WindowParam(glfw.Opened) == 1 { 
     gl.Viewport(0, 0, 1280, 720) 
     gl.ClearColor(1, 0, 0, 1) 
     gl.Clear(gl.COLOR_BUFFER_BIT) // THE CRASH 
     gl.Begin(gl.TRIANGLES) 
     gl.Color3f(1, 0, 0) 
     gl.Vertex3f(-1, -1, 0) 
     gl.Color3f(0, 1, 0) 
     gl.Vertex3f(0, 1, 0) 
     gl.Color3f(0, 0, 1) 
     gl.Vertex3f(1, -1, 0) 
     gl.End() 
     glfw.SwapBuffers() 
     if glfw.Key(glfw.KeyEsc) == 1 { 
      glfw.CloseWindow() 
     } 
    } 
    onExit(nil) 
} 

これは、Windows 7の64ビットの下で罰金のビルドGo 1.0.1 64ビット版。

または細かい場合は取る(またはコメントアウト)gl.Clear(gl.COLOR_BUFFER_BIT)ライン(OpenGLはウィンドウが閉じられるまで、単一の虹色の2D三角形を描画します)動作します。

gl.Clearが(どの引数が渡されても)呼び出されるとすぐに、Windowsは「glfw-win.exeが動作を停止しました...」というメッセージを表示し、Windowsイベントビューアは次のようになります私のためのエラーログ:今すぐ

Faulting application name: glfw-win.exe, version: 0.0.0.0, time stamp: 0x4f9f5ec5 
Faulting module name: glfw-win.exe, version: 0.0.0.0, time stamp: 0x4f9f5ec5 
Exception code: 0xc0000005 
Fault offset: 0x0000000000012883 
Faulting process id: 0xd4c 
Faulting application start time: 0x01cd274e4c69a3d3 
Faulting application path: C:\mytmp\glfw-win\glfw-win.exe 
Faulting module path: C:\mytmp\glfw-win\glfw-win.exe 
Report Id: 8a5bacc0-9341-11e1-911a-d067e544ad7f 

、注目すべきポイントのカップル...

  1. GLFWパッケージは単にgithub.com/jteeuwenとまったく同じAPIを露出したカスタムパッケージです/ glfwではなく内部的にLoadLibrary/GetProコンパイル時のCGO/GCC/LDリンクよりglfw.dllを使用するためのcAddress - 後者は64ビットWindowsでうまく動作しないため、mingw64かgccかcgoが責任を負うかどうかは不明です。 LoadLibrary/GetProcAddressを呼び出すと、glfw.dllの私のカスタム64ビットビルドを呼び出すことができます。明らかな問題は、glパッケージではなくglパッケージを呼び出すことです。

  2. glパッケージは実際には単にthis oneで、変更されていません。私は、-m64 -lmingw32 -Wl、/ windows/opengl32.dllなどのいくつかのLDFLAGSの変更を試しましたが、違いはありません。gl.Clear()が呼び出されていない限り、私は元に戻りました。もちろん、後でOpenGL 4.2に移行します。

  3. Process Explorerを使用すると、自分のプロセスが64ビットであり、ロードされたすべてのDLLが64ビットイメージ(opengl32.dllとglfw.dllを含む)であることがわかります。

  4. "gl21パッケージがopengl32.dllによってエクスポートされたglClear()関数の有効なアドレスを取得できなかった可能性がありますか?" - おそらく:line 2926によると、gl.Init()への私の呼び出しは、この場合に失敗します。

  5. GPUドライバに問題がありますか?さらにそうではありません。最も新しい正式なnVidia Quadro 5010Mドライバ296.35がインストールされています。また、 "パフォーマンスドライバ"を試してみましたが、とにかくまったく同じドライバであるようです。 nVidia Control PanelによるOpenGL 4.2の完全なサポート(opengl32.dllは2009年となっていますが、とにかく、現在2.1を目標にしています)。さらに、GLFWサンプルプログラムのparticles.exeと同様に、「Geeks3D GPU Caps Viewer」および「Shader Toy Mark」のOpenGLシェーダも実行されます。それらのすべてでglClear()も使用されます。

  6. gl21の代わりにgl42を使用すると、まったく同じ問題が発生するため、その原因でもありません。

何をするために、どのように進めるために...他のすべてのgl.SomeExportedFunc()の呼び出しは、この例ではクラッシュしていないか注意していますか?

これはgl.Clear()と他のfuncでしか起こらないのであればこれで生きることができます - とにかくカスタムコンテンツのフルスクリーンクワッドをレンダリングするだけですが、私はかなり早い段階ですWin64はここにあります(gl64コードはLinux64でうまく動作していますが、現在はWin64に移植しています)。後で追加の呼び出しで同じ問題が発生することになりますので、これを今報告しています。私は間もなくこれによって影響を受ける他の通話を見つけるでしょう。

答えて

0

Go、GLFW、Mingw-w64の最新リリースでは、もはや問題はありません。

1

CGOで生成されたスタブがなくてもC関数を呼び出すことはできません。

+0

あなたの考えをありがとう...しかし、これは実際にここには当てはまりません:私は* gl * View *(gl.Begin()など)を呼び出すことができます。もちろん、適切なgl21.a libは、\ go \ pkg \ windows_amd64 \ github.com \ chsc \ goglの下に置かれ、 "go build"を介して完全にビルドされます。したがって暗黙的にCGOになります。すべて。 gl.Clear()だけがアクセス違反(これまで)を与えていますが、これまでにテストしたgl21.a関数はありません。 – metaleap

+0

Go/C境界を越えるには、新しいスレッドでスタックを設定し、非分割にする必要があります。いくつかの単純なケースで誤って動作するかもしれませんが、一般的なケースの要件は削除されません。 – zzzz

+0

GitHubなどの既成のinteropパッケージ(CGOに基づいて構築されたもの)の95%が本質的に役に立たないということですか? launchpad.net/mgo ... github.com/jteeuwen/glfw ... github.com/chsc/gogl ...多くの人が、Linux上で過去3ヶ月間、問題なく、そして無数に他のGoはそこにいる。 Win32でも99%のケースでサポートされていれば、Win64ではほとんどの場合[* cough * gl.Clear()を除きます。 その場合、なぜ "設定してスタックを分割しない"というのはどこに説明されていませんか? – metaleap

関連する問題