使用SkiaSharp、WPF与.NET 8(/clr:netcore)结合时出现异常及原生DLL缺失问题求助
使用SkiaSharp、WPF与.NET 8(/clr:netcore)结合时出现异常及原生DLL缺失问题求助
大家好,我现在碰到一个卡了好久的问题:我的项目是用托管C++/CLR做桥接层,让老MFC代码和新的WPF项目交互,WPF里用SkiaSharp做矢量图渲染。现在切换到.NET 8环境后彻底卡壳了,具体情况如下:
核心问题现象
- .NET Framework 4.8完全正常:不管是SkiaSharp的原生DLL输出,还是整个MFC→桥接层→WPF的流程都没毛病。
- .NET 8下直接崩:只要在WPF里创建最简单的SKBitmap(比如
var bmp = new SKBitmap(1, 1);),就会抛出未处理异常:Unhandled exception at 0x767EF4C4 (KernelBase.dll) in MyProject.exe: 0xE0434352 (parameters: 0x80070002, 0x00000000, 0x00000000, 0x00000000, 0x533A0000). - 更诡异的是:.NET 8环境下,SkiaSharp的原生DLL根本不会出现在任何输出目录里,而.NET Framework下这些DLL会乖乖跑到正确位置。
我已经试过的排查操作
- 换过N个版本的SkiaSharp及其依赖包(从最新版往旧版试了个遍)
- 调整过不同的Windows目标版本(Windows 10、Windows 11都试过)
- 单独测试过.NET 8的WPF和桥接层交互(不含SkiaSharp),完全正常,说明桥接逻辑没问题
项目结构与关键代码
我的项目流程是:MFC程序 → 托管C++/CLR桥接层 → .NET 8 WPF控件(集成SkiaSharp)
1. WPF控件核心代码(触发异常的位置)
using System.Windows; using System.Windows.Controls; using SkiaSharp; using SkiaSharp.Views.Desktop; namespace MyControls { public partial class MyUserControls : UserControl { public delegate void MessageHandler(int message, string? data); public event MessageHandler? OnMessageSend; public MyUserControls() { InitializeComponent(); var bmp = new SKBitmap(1, 1); // 就是这行代码触发了异常 } } }
2. 托管C++/CLR桥接层代码(已添加WPF项目引用)
#include <windows.h> #include "WpfBridge.h" #include <vcclr.h> #include <corecrt_wstdio.h> static gcroot<MyControls::MyUserControls^> control; static NativeTextCallback NativeCallback = nullptr; void SetNativeCallback(NativeTextCallback callback) { NativeCallback = callback; } void OnMesssageFromWpf(int message, System::String^ data) { // 把托管字符串转成非托管CString pin_ptr<const wchar_t> wch = PtrToStringChars(data); CString nativeStr(wch); // 默认是CStringW类型 NativeCallback(message, nativeStr); } void ShowWpfInWindow(void* hwnd) { System::IntPtr handle(hwnd); HWND nativeHwnd = static_cast<HWND>(hwnd); RECT rect; GetClientRect(nativeHwnd, &rect); int width = rect.right - rect.left; int height = rect.bottom - rect.top; System::Windows::Interop::HwndSourceParameters^ sourceParams = gcnew System::Windows::Interop::HwndSourceParameters("WpfHost"); sourceParams->ParentWindow = handle; sourceParams->WindowStyle = WS_VISIBLE | WS_CHILD; sourceParams->PositionX = 0; sourceParams->PositionY = 50; sourceParams->Width = width; sourceParams->Height = height; System::Windows::Interop::HwndSource^ source = gcnew System::Windows::Interop::HwndSource(*sourceParams); control = gcnew MyControls::MyUserControls(); control->OnMessageSend += gcnew MyControls::MyUserControls::MessageHandler(&OnMesssageFromWpf); source->RootVisual = control; }
3. MFC侧调用桥接层的代码
#include <stdafx.h> #include "MfcWindow.h" #define MENU_HEIGHT_PIXELS 20 IMPLEMENT_DYNAMIC(MfcWindow, CWnd) MfcWindow::MfcWindow(CWnd* parentWnd) { m_WpfBridgeDll = LoadLibrary(L"WpfBridge.dll"); m_ParentWnd = parentWnd; if (m_WpfBridgeDll == nullptr) throw new exception; ShowWpfInMfcWindow = (ShowWpfInWindowFunc)GetProcAddress(m_WpfBridgeDll, "ShowWpfInWindow"); SetCallback = (SetCallbackFunc)GetProcAddress(m_WpfBridgeDll, "SetNativeCallback"); } MfcWindow::~MfcWindow() {} void __cdecl MfcWindow::MyNativeHandler(int message, CString& data) { switch (message) { // 处理WPF传过来的消息逻辑 } } void MfcWindow::WpfBridgeLoader() { if (m_WpfBridgeDll == nullptr) return; if (ShowWpfInMfcWindow && SetCallback) { SetCallback(&MyNativeHandler); ShowWpfInMfcWindow((void*)m_hWnd); // 执行到这里就触发了异常 } }
现在我最懵的就是:为什么.NET 8下SkiaSharp的原生DLL完全不会被复制到输出目录?这应该是导致后续异常的根本原因,但我试了各种常规操作都没解决,有没有大佬遇到过类似场景,或者能给点排查方向?
内容来源于stack exchange
相关产品推荐
相关产品推荐

