P / Invoking" wglChoosePixelFormatARB"使堆栈失衡

时间:2017-02-15 04:29:02

标签: c# windows opengl pinvoke wgl

我正在尝试使用一些pinvokes为某些单元测试设置wgl上下文,但是(到目前为止)我的一个方法使堆栈失衡。

我所做的是先创建一个窗口并获取其DC。这一切都正常,因为我正在与kernel32,user32,gdi32库进行通信。我想用OpenGL绘制一个pbuffer,为了创建PB,我需要使用扩展。这需要我有一个背景......到目前为止,这一切都很正常并且正常工作。

当我尝试创建pbuffer时出现问题。当我尝试使用wglChoosePixelFormatARB进行配置时,这似乎会使堆栈失衡。我之前刚刚执行了另一个ARB方法(wglGetExtensionsStringARB)来检查扩展 - 并且使用相同的父DC工作正常。

所以,代码......我的代表看起来像这样:

[UnmanagedFunctionPointer(CallingConvention.Winapi)]
[return: MarshalAs(UnmanagedType.Bool)]
public delegate bool wglChoosePixelFormatARBDelegate(
    IntPtr dc,
    [In] int[] attribIList,
    [In] float[] attribFList,
    uint maxFormats,
    [Out] int[] pixelFormats,
    out uint numFormats);

我发现它是这样的:

[DllImport(opengl32)]
public static extern IntPtr wglGetProcAddress(string lpszProc);
// ...
var ptr = wglGetProcAddress("wglCreatePbufferARB");
wglCreatePbufferARB = Marshal.GetDelegateForFunctionPointer(ptr, typeof(wglChoosePixelFormatARBDelegate));

我正在调用它:

var iAttrs = new int[]
{
    Wgl.WGL_ACCELERATION_ARB, Wgl.WGL_FULL_ACCELERATION_ARB,
    Wgl.WGL_DRAW_TO_WINDOW_ARB, Wgl.TRUE,
    Wgl.WGL_SUPPORT_OPENGL_ARB, Wgl.TRUE,
    Wgl.NONE, Wgl.NONE
};
var fAttrs = new float[2];
var piFormats = new int[1];
uint nFormats;
wglChoosePixelFormatARB(
    parentDC, 
    iAttrs,
    fAttrs, 
    (uint)piFormats.Length, 
    piFormats, 
    out nFormats);
if (nFormats == 0)
{
    return IntPtr.Zero;
}

var pbuf = extensions.wglCreatePbufferARB(parentDC, piFormats[0], 1, 1, null);

本机方面(未导出):

BOOL WINAPI wglChoosePixelFormatARB (
    HDC hdc, 
    const int *piAttribIList, 
    const FLOAT *pfAttribFList, 
    UINT nMaxFormats, 
    int *piFormats,
    UINT *nNumFormats);

函数def就是这样:

typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (
    HDC hdc, 
    const int *piAttribIList, 
    const FLOAT *pfAttribFList, 
    UINT nMaxFormats, 
    int *piFormats, 
    UINT *nNumFormats);

代码看起来不错,但肯定有错误:)我希望有人可以指出我的错误。

如果需要更多代码,我将所有内容都放在一个简单的控制台应用程序中: https://gist.github.com/mattleibow/755eba3c8ff5eafb9549842a0abb0426

(代码有大量的注释,这只是因为我忙于从C ++移植到C#。而且三分之一的代码只是dllimports / structs / enums)

1 个答案:

答案 0 :(得分:2)

函数声明看起来很合理但似乎只是导入了错误的函数。

您想要wglChoosePixelFormatARB但实际导入wglCreatePbufferARB。这闻起来像一个类复制/粘贴SNAFU。

通过更正传递给GetProcAddress的名称来解决此问题。