【问题标题】:P/Invoking "wglChoosePixelFormatARB" Unbalances the StackP/Invoking "wglChoosePixelFormatARB" 使堆栈失衡
【发布时间】:2017-02-15 14:01:34
【问题描述】:

我正在尝试使用一些 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

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

【问题讨论】:

  • 你明白警告的意思吗?如果是这样,那么您将意识到我们也需要查看非托管声明。
  • @DavidHeffernan gotcha,忘记了。

标签: c# windows opengl pinvoke wgl


【解决方案1】:

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

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

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

【讨论】:

  • 认真的吗?我检查了所有东西,除了该死的字符串?已经在这里待了几个小时了……谢谢!看来我确实需要那种睡眠。 m.memegen.com/qis49q.jpg
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-10
  • 1970-01-01
  • 1970-01-01
  • 2016-05-06
  • 1970-01-01
相关资源
最近更新 更多