I am trying to use some pinvokes to set up a wgl context for some unit tests, but (so far) one of my methods unbalances the stack.
What I have done is to first create a window and get its DC. This all works as I am talking to the kernel32, user32, gdi32 libraries. I am wanting to draw to a pbuffer with OpenGL, and in order to create the PB, I need to use the extensions. Which requires that I have a context... This is all sadly normal and working so far.
The problem comes when I am trying to create the pbuffer. When I try get the configurations using wglChoosePixelFormatARB
, this appears to unbalance the stack. I have just executed another ARB method (wglGetExtensionsStringARB
) earlier to check the extensions - and that works fine using the same parent DC.
So, on to code... My delegate looks like this:
[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);
I find it like this:
[DllImport(opengl32)]
public static extern IntPtr wglGetProcAddress(string lpszProc);
// ...
var ptr = wglGetProcAddress("wglCreatePbufferARB");
wglCreatePbufferARB = Marshal.GetDelegateForFunctionPointer(ptr, typeof(wglChoosePixelFormatARBDelegate));
And I am invoking it like this:
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);
The native side of this is (which is not exported):
BOOL WINAPI wglChoosePixelFormatARB (
HDC hdc,
const int *piAttribIList,
const FLOAT *pfAttribFList,
UINT nMaxFormats,
int *piFormats,
UINT *nNumFormats);
And the function def is this:
typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (
HDC hdc,
const int *piAttribIList,
const FLOAT *pfAttribFList,
UINT nMaxFormats,
int *piFormats,
UINT *nNumFormats);
The code looks OK to me, but there must be something wrong :) I hope someone can point out my error.
In case more code is required, I have it all here in a single file that is just a plain console app: https://gist.github.com/mattleibow/755eba3c8ff5eafb9549842a0abb0426
(the code has large chunks of comments, this is just because I am busy porting from C++ to C#. And a third of the code is just the dllimports/structs/enums)
The function declaration looks reasonable but it seems that you are simply importing the wrong function.
You want
wglChoosePixelFormatARB
but actually importwglCreatePbufferARB
. This smells like a class copy/paste SNAFU.Fix this by correcting the name that you pass to
GetProcAddress
.