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

如何在无UWP UI的C++ DLL中调用C++/WinRT的LampArray API?

在无UWP UI依赖的C++ DLL中使用LampArray DeviceWatcher

完全可以在独立的C++ DLL中调用LampArray相关API,无需依赖UWP UI组件。原示例的耦合点在于使用了UI页面类的弱引用(get_weak())和类成员回调,只需将这部分逻辑替换为独立的事件处理机制即可。

核心解决方案步骤

  • 移除UI类依赖:创建DLL专属的设备管理类,替代原UI页面类的角色,用于管理DeviceWatcher和设备列表。
  • 使用Lambda或独立回调函数:通过Lambda捕获管理类的弱引用(避免悬垂指针),或者使用普通函数结合上下文指针来处理设备添加/移除事件。
  • 正确管理事件Revoker生命周期:将event_token_revoker保存为管理类的成员,确保在类销毁时自动注销事件,避免资源泄漏。

示例实现代码

#include <winrt/Windows.Devices.Lights.h>
#include <winrt/Windows.Foundation.h>
#include <vector>
#include <algorithm>

namespace winrt::LampArrayDll::implementation
{
    class LampDeviceManager
    {
    public:
        LampDeviceManager()
        {
            // 创建设备监视器
            m_deviceWatcher = winrt::Windows::Devices::Lights::LampArray::CreateWatcher();

            // 注册设备添加事件:用弱引用捕获当前实例,避免生命周期问题
            m_deviceAddedRevoker = m_deviceWatcher.Added(winrt::auto_revoke, 
                [weakThis = get_weak()](auto const&, winrt::Windows::Devices::Lights::LampArray const& lampArray)
                {
                    if (auto strongThis = weakThis.lock())
                    {
                        strongThis->OnDeviceAdded(lampArray);
                    }
                });

            // 注册设备移除事件
            m_deviceRemovedRevoker = m_deviceWatcher.Removed(winrt::auto_revoke,
                [weakThis = get_weak()](auto const&, winrt::Windows::Devices::Lights::LampArrayRemovedEventArgs const& args)
                {
                    if (auto strongThis = weakThis.lock())
                    {
                        strongThis->OnDeviceRemoved(args.DeviceId());
                    }
                });

            // 启动监视器
            m_deviceWatcher.Start();
        }

        ~LampDeviceManager()
        {
            // 停止监视器,避免后台线程持续运行
            if (m_deviceWatcher.Status() == winrt::Windows::Devices::Enumeration::DeviceWatcherStatus::Started)
            {
                m_deviceWatcher.Stop();
            }
        }

        // 对外暴露的接口:获取当前连接的所有灯设备
        std::vector<winrt::Windows::Devices::Lights::LampArray> GetConnectedLamps()
        {
            std::vector<winrt::Windows::Devices::Lights::LampArray> lamps;
            // 同步枚举所有设备
            auto deviceCollection = winrt::Windows::Devices::Lights::LampArray::FindAllAsync().get();
            for (auto const& lamp : deviceCollection)
            {
                lamps.push_back(lamp);
            }
            return lamps;
        }

    private:
        // 设备添加处理逻辑
        void OnDeviceAdded(winrt::Windows::Devices::Lights::LampArray const& lampArray)
        {
            m_connectedLamps.push_back(lampArray);
            // 这里可以添加自定义逻辑,比如通知上层设备已添加
        }

        // 设备移除处理逻辑
        void OnDeviceRemoved(hstring const& deviceId)
        {
            auto it = std::remove_if(m_connectedLamps.begin(), m_connectedLamps.end(),
                [&deviceId](const auto& lamp) { return lamp.DeviceId() == deviceId; });
            m_connectedLamps.erase(it, m_connectedLamps.end());
            // 这里可以添加自定义逻辑,比如通知上层设备已移除
        }

        winrt::Windows::Devices::Lights::LampArrayWatcher m_deviceWatcher;
        winrt::event_token_revoker<winrt::Windows::Devices::Lights::LampArrayAddedEventHandler> m_deviceAddedRevoker;
        winrt::event_token_revoker<winrt::Windows::Devices::Lights::LampArrayRemovedEventHandler> m_deviceRemovedRevoker;
        std::vector<winrt::Windows::Devices::Lights::LampArray> m_connectedLamps;
    };
}

// 对外暴露的DLL接口示例
extern "C" __declspec(dllexport) void* CreateLampManager()
{
    return new winrt::LampArrayDll::implementation::LampDeviceManager();
}

extern "C" __declspec(dllexport) void DestroyLampManager(void* manager)
{
    delete static_cast<winrt::LampArrayDll::implementation::LampDeviceManager*>(manager);
}

关键注意事项

  • 编译配置:确保DLL项目启用C++/WinRT支持,并链接Windows SDK中的windows.devices.lights.lib库。
  • 线程安全:DeviceWatcher的事件会在后台线程触发,若回调逻辑涉及共享资源访问,需添加线程同步(如临界区、mutex)。
  • 权限配置:若DLL被桌面应用调用,需在应用清单中声明设备权限:
    <Capabilities>
      <DeviceCapability Name="lowLevel" />
    </Capabilities>
    
  • 生命周期管理:在DLL对外接口中,需提供明确的创建/销毁方法,确保LampDeviceManager实例被正确释放,避免资源泄漏。

内容的提问来源于stack exchange,提问作者sunil

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 13:28:17