I've begun creating a simple game engine using Direct2D, but I've encountered an issue of getting a seg fault whenever I release the IWICImagingFactory*. The issue only occurs when the program is closed.
Minimal Reproducible Sample:
#include <Windows.h>
#include <d2d1.h>
#include <wincodec.h>
template <class Interface>
void SafeRelease(
Interface *&pInterfaceToRelease)
{
if (pInterfaceToRelease != nullptr)
{
pInterfaceToRelease->Release();
pInterfaceToRelease = nullptr;
}
}
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPWSTR pCmdLine, int nCmdShow)
{
// Register Window Class
WNDCLASS wc = {};
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInst;
wc.lpszClassName = L"Class Name";
RegisterClass(&wc);
// Create and Show Window
HWND hWnd = CreateWindowEx(0, L"Class Name", L"Test Window", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInst, NULL);
ShowWindow(hWnd, nCmdShow);
// Create d2d factory and render target
ID2D1Factory *pD2DFactory;
ID2D1HwndRenderTarget *pRT;
D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &pD2DFactory);
RECT rc;
GetClientRect(hWnd, &rc);
pD2DFactory->CreateHwndRenderTarget(
D2D1::RenderTargetProperties(),
D2D1::HwndRenderTargetProperties(hWnd, D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top)),
&pRT);
// Create Imaging Factory
IWICImagingFactory *pWICFactory;
CoCreateInstance(CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pWICFactory));
// Start loop
bool windowOpen = true;
MSG msg;
while (windowOpen)
{
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (msg.message == WM_QUIT)
{
SafeRelease(pWICFactory);
SafeRelease(pRT);
SafeRelease(pD2DFactory);
UnregisterClass(L"Class Name", hInst);
CoUninitialize();
windowOpen = false;
break;
}
pRT->BeginDraw();
pRT->Clear(D2D1::ColorF(D2D1::ColorF::CornflowerBlue));
pRT->EndDraw();
}
return 0;
}
I'm compiling the program using gcc:
g++ -fdiagnostics-color=always -g test.cpp -municode -mwindows -ld2d1 -lole32 -lwindowscodecs -o test.exe
I've tried eliminated any use of the IWICImagingFactory* beyond creating it by not loading any images, but the issue persists. Images still load fine. I also ensured that the pointer isn't null before calling Release().
Thank you to everyone who replied. The issue with the code sample I provided was that it didn't call CoInitialize()
, which I forgot to include. The issue with my program itself was that there was an object that held a ID2D1Bitmap*
that was created with the IWICImagingFactory
and stored in static memory. The problem was that the bitmap was being released after the IWICImagingFactory
, which caused a seg fault.