You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 10:33:09