在 C++ DLL 中,我初始化了 Direct2D,然后初始化了一些绘制函数。当调用
pRenderTarget->Clear(...)
时,它会抛出 AccessViolationException(尝试访问受保护的内存...)。
这是示例:
DLL_EXPORT void Direct2D_Init(HWND _hwnd, UINT width, UINT height)
{
D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &pD2DFactory);
// Create WIC factory
HRESULT hr = CoCreateInstance(CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER,
IID_IWICImagingFactory, reinterpret_cast<void**>(&g_pWICFactory));
if (FAILED(hr))
{
// Handle error
return;
}
// Create a render target
D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties(
D2D1_RENDER_TARGET_TYPE_DEFAULT, D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED));
pD2DFactory->CreateHwndRenderTarget(props, D2D1::HwndRenderTargetProperties(_hwnd, D2D1::SizeU(width, height)), &pRenderTarget);
}
// Exception is thrown when invoking this:
DLL_EXPORT void Direct2D_Clear()
{
pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));
}
[DllImport(".\\d2dlib.dll")]
static extern void Direct2D_Clear();
public void Begin()
{
if (renderOption == RenderOption.Direct2D)
{
Direct2D_Clear(); // System.AccessViolationException: 'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.'
}
else
...
}
可能出了什么问题?这看起来很不寻常。
直接在C++中运行绘图循环似乎没有问题。这似乎是有效的:
// The same init method as already displayed
Direct2D_Init(hWnd, 800, 600);
while (true)
{
pRenderTarget->BeginDraw();
pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::CornflowerBlue));
pRenderTarget->EndDraw();
}
在 C# 程序的上下文之外,我相信这可能就是我编写 DLL 的方式。 DLL 和 C# 程序都编译为 x64。或者关于 PInvoke 的东西。
问题出在窗口创建上,正如所建议的那样。当我创建 WinForm 窗口并使用其句柄时,会导致此异常。我在应用此方法来获取窗口时发现了这一点:
if (RewBatch.renderOption == RenderOption.Direct2D || RewBatch.renderOption == RenderOption.Both)
{
Process proc = Process.Start(".\\TestBed.exe");
START:
if (proc.MainWindowHandle == IntPtr.Zero)
{
Task.WaitAll(Task.Delay(100));
proc.Refresh();
goto START;
}
Direct2D_InitEx(handle = proc.MainWindowHandle, (uint)window.Width, (uint)window.Height);
}
我创建了一个具有特定窗口尺寸的 CPP 应用程序,并使用该窗口的句柄。这是一个基本的解决方案。我不太确定为什么 WinForms 尝试停止工作,但我一直在对敏感代码进行大量更新。